 	}
 	
 	~Matrix() {
-		if (! isOriginal_)
+		if (*smart_ptr_counter_ > 1) {
+			(*smart_ptr_counter_) -= 1;
 			return;
+		}
+		
+		delete smart_ptr_counter_;
 		
 		if (isCPU_)
 			delete [] data_;

	const unsigned int width_;
	const unsigned int height_;
	const bool isCPU_;
	const bool isOriginal_;
	
	float *data_;

public:
	
	Matrix(const unsigned int &width, const unsigned int &height, const bool &isCPU) : width_(width), height_(height), isCPU_(isCPU), isOriginal_(true) {
		if (isCPU_)
			data_ = new float[width_ * height_];
		else
			cudaMalloc(&data_, width_ * height_ * sizeof(float));
	}
	
	Matrix(const Matrix &m) : width_(m.width_), height_(m.height_), data_(m.data_), isCPU_(m.isCPU_), isOriginal_(false) {}
	
	Matrix(const Matrix &m, const bool &isCPU) : width_(m.width_), height_(m.height_), isCPU_(isCPU), isOriginal_(true) {
		if (isCPU_) {
			data_ = new float[width_ * height_];
			if (m.isCPU_)

	}
	
	~Vector() {
		if(*smart_ptr_counter_ > 1) {// cuda-kernel constructs a copy of the object and then call its destructor
			(*smart_ptr_counter_) -= 1;
			return;
		}
		
		delete smart_ptr_counter_;
		
		if (isCPU_)
			delete [] data_;
		else
