There was a problem writing the copying class. The main object and its copy have a common memory address. How to separate them, while preserving the value in the main object and in its copy? Here is the code itself. Upon completion of the program gives an error as in the screenshot. Also tried to add exception handling. Underlines all BadIndex s. How to fix it?

 #include <iostream> using namespace std; class INT { public: INT(unsigned _x, unsigned _y); INT(INT &I) :x(Ix), y(Iy), data(new int[x* y]) { data = &(I.data[1,2]); }; int& operator () (unsigned _x, unsigned _y); int operator () (unsigned _x, unsigned _y) const; ~INT(); private: unsigned x, y; int *data; }; inline INT::INT(unsigned _x, unsigned _y): x(_x), y(_y) { if (x == 0 || y == 0) throw BadIndex("Массив имеет нулевой размер"); data = new int[_x* _y]; } inline INT::~INT() { delete[] data; } inline int& INT::operator() (unsigned _x, unsigned _y) { if (_x >= x || _y >= y) throw BadIndex("Выбранный элемент находится вне массива"); return data[x*_x + _y]; } inline int INT::operator() (unsigned _x, unsigned _y) const { if (_x >= x || _y >= y) throw BadIndex("Выбранный элемент находится вне массива"); return data[x*_x + _y]; } int main() { INT a(10, 10); cin >> a(1,2); INT b(a); cout << "RESULT" << endl; cout << a(1, 2) << endl; cout << b(1, 2) << endl; return 0; } 

error example

  • Um, how can you have one address and different meanings? Looks like we need a COW technique. - m0nhawk

1 answer 1

Your copy constructor is wrong. You write this:

 INT(INT &I) : x(Ix), // скопировать значение х y(Iy), // скопировать значение y data(new int[x * y]) // завести новый массив data нужного размера { data = &(I.data[1,2]); // Оппаньки! Затереть указатель на выделенный массив, // и прописать в него указатель на кусок старых данных }; 

As a result, data will be deleted twice in the destructor.

This is a gross mistake, do not do so. Apparently, you just need to copy the data. You can use, for example, std::copy_n :

 { // data = &(I.data[1,2]); // <-- неправильно std::copy_n(I.data, x * y, data); } 

For Visual Studio, you'll have to turn around, since the standard functions there are not considered safe enough. The following trick should work :

 std::copy_n(I.data, x * y, stdext::checked_array_iterator<int*>(data, x * y)); 

No exception handling is needed. Write the code correctly, and do not try to suppress error messages.


By the way, since I.data is not a multidimensional array, in the expression I.data[1,2] , it appears that operator , I.data[1,2]

  • Swears at copy: Error 1 error C4996: 'std :: _ Copy_n': To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. Visual C ++ 'Checked Iterators' - desuev
  • @desuev: What is your version of Visual Studio? - VladD
  • one
    It is a mistake, not a warning? However, I have #if defined(_MSC_VER) #pragma warning(disable : 4996) in my source code for a long time #if defined(_MSC_VER) #pragma warning(disable : 4996) ... - user6550
  • @VladD VS 2013 version. And it is an error. - desuev
  • @klopp: Probably warnings are written in the project - VladD