繁体   English   中英

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

[英]Copy constructor of dynamic two-dimensional array

我需要帮助。 现在我正在尝试创建一个类 Matrix,但是每次我在 Visual Studio 2013 中运行它时我的程序都会冻结。我认为复制构造函数存在一些问题。 这是整个代码。 `

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();
}

`

函数“ShowMatrixOnScreen”在屏幕上打印矩阵“x”,但随后控制台冻结。

你的析构函数有语句delete[] matrix[X];

matrix[X]不存在,因此您正在释放未分配给您的内存,这是未定义的行为。 它应该是delete [] matrix[i]

此外,正如来自莫斯科的 Vlad 所指出的,建议delete所有内存,因此您还应考虑添加delete [] matrix ,以删除您使用matrix = new int*[X];分配的一维指针数组matrix = new int*[X];

问题是你的析构函数无效

首先在这个循环中

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

它尝试访问分配的数组之外不存在的元素matrix[X] 索引的有效范围是[0, X - 1]

所以你必须写

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

但是只有当matrix不等于nullptr ,这个循环才有效。因此,在循环之前,您必须检查matrix是否等于nullptr

并且您还需要删除分配给第一个一维数组的内存

delete [] matrix;

因此析构函数看起来像

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

    delete []matrix;
}

同样在复制构造函数中,您还应该检查复制对象的数据成员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];
            }
        }
    }
}

如果数据成员XY类型为size_t会好得多。 否则,您还需要检查它们是否不是负数。

内存的分配可以放在一个单独的私有成员函数中。

例如

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;
}

在类定义中,数据成员XY应位于数据成员矩阵之前

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

在这种情况下,您可以使用构造函数的 mem-initializer 列表来初始化类数据成员。

例如

// 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;
            }
        }
    }
}

并且默认构造函数可以像这样定义

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

反过来,复制构造函数可以定义为

// 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];
            }
        }
    }
}

您还应该定义复制赋值运算符或将其定义为已删除。 否则,当您尝试将类的一个对象分配给另一个时会出现问题。

考虑到函数 main 的返回类型为int

int main()

暂无
暂无

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

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