简体   繁体   English

动态二维数组的复制构造函数

[英]Copy constructor of dynamic two-dimensional array

I need help.我需要帮助。 Now i'm trying to make a class Matrix, but my program freezes every time I run it in Visual Studio 2013. I think there is some trouble with copy constructor.现在我正在尝试创建一个类 Matrix,但是每次我在 Visual Studio 2013 中运行它时我的程序都会冻结。我认为复制构造函数存在一些问题。 Here is the whole code.这是整个代码。 ` `

class Matrix
{
private:
    int** matrix;
    int X; // Matrix rows
    int Y; // Matrix columns
public:
    // Default Constructor
    Matrix()
    {
        X = 0;
        Y = 0;
        matrix = NULL;
    }
    // Constructor with parameters
    Matrix(int _X, int _Y)
    {
        srand(time(NULL));

        X = _X;
        Y = _Y;
        matrix = new int*[X];

        for (int i = 0; i < X; i++)
                matrix[i] = new int[Y];

        for (int i = 0; i < X; i++)
        {
            for (int j = 0; j < Y; j++)
            {
                matrix[i][j] = rand() % 100;
            }
        }

    }
    // Copy constructor
    Matrix(const Matrix& N)
    {
        X = N.X;
        Y = N.Y;

        matrix = new int*[X];

        for (int i = 0; i < X; i++)
            matrix[i] = new int[Y];

        for (int i = 0; i < X; i++)
        {
            for (int j = 0; j < Y; j++)
            {
                matrix[i][j] = N.matrix[i][j];
            }
        }
    }
    // Destructor
    ~Matrix()
    {
        for (int i = 0; i < X; i++)
            delete[] matrix[X];
    }
    //--------------------------------------
    void ShowMatrixOnScreen()
    {
        for (int i = 0; i < X; i++)
        {
            for (int j = 0; j < Y; j++)
                cout << matrix[i][j] << "   ";

            cout << endl << endl;
        }
    }
};

void main() 
{
    Matrix x(4, 2);
    x.ShowMatrixOnScreen();
}

` `

Function "ShowMatrixOnScreen" prints matrix "x" on a screen, but then console freezes.函数“ShowMatrixOnScreen”在屏幕上打印矩阵“x”,但随后控制台冻结。

Your destructor has the statement delete[] matrix[X];你的析构函数有语句delete[] matrix[X];

matrix[X] does not exist, so you are freeing memory which is not allocated to you, which is Undefined Behavior. matrix[X]不存在,因此您正在释放未分配给您的内存,这是未定义的行为。 It should be delete [] matrix[i] instead!它应该是delete [] matrix[i]

Moreover, as pointed by Vlad From Moscow, it is advisable to delete all the memory, so you shall also consider adding delete [] matrix , to delete the 1-D array of pointers which you allocated using matrix = new int*[X];此外,正如来自莫斯科的 Vlad 所指出的,建议delete所有内存,因此您还应考虑添加delete [] matrix ,以删除您使用matrix = new int*[X];分配的一维指针数组matrix = new int*[X];

The problem is that your destructor is invalid问题是你的析构函数无效

First of all in this loop首先在这个循环中

    for (int i = 0; i < X; i++)
        delete[] matrix[X];

it tries to access non-existent element matrix[X] beyond the allocated array.它尝试访问分配的数组之外不存在的元素matrix[X] The valid range for indices is [0, X - 1]索引的有效范围是[0, X - 1]

So you have to write所以你必须写

    for (int i = 0; i < X; i++)
        delete[] matrix[i];
                       ^^^

But thsi loop is valid only if matrix is not equal to nullptr Therefore before the loop you have to check whether matrix is equal to nullptr or not equal.但是只有当matrix不等于nullptr ,这个循环才有效。因此,在循环之前,您必须检查matrix是否等于nullptr

And also you need to delete the memory allocated to the first one-dimensionl array并且您还需要删除分配给第一个一维数组的内存

delete [] matrix;

Thus the destructor will look like因此析构函数看起来像

~Matrix()
{
    if ( matrix )
    {
        for ( int i = 0; i < X; i++ ) delete []matrix[i];
    }

    delete []matrix;
}

Also in the copy constructor you should also check whether data member matrix of the copied object also is not equal to nullptr同样在复制构造函数中,您还应该检查复制对象的数据成员matrix是否也不等于nullptr

// Copy constructor
Matrix(const Matrix& N)
{
    X = N.X;
    Y = N.Y;

    if ( N.matrix )
    {
        matrix = new int*[X];

        for (int i = 0; i < X; i++)
            matrix[i] = new int[Y];

        for (int i = 0; i < X; i++)
        {
            for (int j = 0; j < Y; j++)
            {
                matrix[i][j] = N.matrix[i][j];
            }
        }
    }
}

It would be much better if data members X and Y has type size_t .如果数据成员XY类型为size_t会好得多。 Otherwise you need also to check whether they are not negative.否则,您还需要检查它们是否不是负数。

The allocation of the memory could be placed in a separate private member function.内存的分配可以放在一个单独的私有成员函数中。

for example例如

int ** allocate( size_t m, size_t n )
{
    int **p = nullptr;

    if ( n != 0 && m != 0 )
    {
        matrix = new int *[m];

        for ( size_t i = 0; i < m; i++ ) matrix[i] = new int[n];
    }

    return p;
}

In the class definition data members X and Y should precede data member matrix在类定义中,数据成员XY应位于数据成员矩阵之前

private:
    int X; // Matrix rows
    int Y; // Matrix columns    
    int** matrix;

In this case you could use mem-initializer list of constructors to initialize the class data members.在这种情况下,您可以使用构造函数的 mem-initializer 列表来初始化类数据成员。

For example例如

// Constructor with parameters
Matrix(int X, int Y) : X( X ), Y( Y ), matrix( allocate( X, Y ) )
{
   if ( matrix )
   {
       srand(time(NULL));

        for (int i = 0; i < X; i++)
        {
            for (int j = 0; j < Y; j++)
            {
                matrix[i][j] = rand() % 100;
            }
        }
    }
}

And the default constructor could be defined like并且默认构造函数可以像这样定义

// Default Constructor
Matrix() : Matrix( 0, 0 )
{
}

In turn the copy constructor could be defined like反过来,复制构造函数可以定义为

// Copy constructor
Matrix( const Matrix &N ) : X( N.X ), Y( N.Y ), matrix( allocate( N.X, N.Y ) )
{
    if ( matrix )
    {
        for (int i = 0; i < X; i++)
        {
            for (int j = 0; j < Y; j++)
            {
                matrix[i][j] = N.matrix[i][j];
            }
        }
    }
}

And you should define also the copy assignment operator or define it as deleted.您还应该定义复制赋值运算符或将其定义为已删除。 Otherwise there will be problems when you try to assign one object of the class to another.否则,当您尝试将类的一个对象分配给另一个时会出现问题。

Take into account that function main shall have return type int考虑到函数 main 的返回类型为int

int main() int main()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM