动态二维数组的复制构造函数
Copy constructor of dynamic two-dimensional array
我需要帮助。现在我正在尝试制作一个 class 矩阵,但是我的程序在 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 From Moscow 所指出的,建议 delete
所有内存,因此您还应考虑添加 delete [] matrix
,以删除您要删除的一维指针数组使用 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];
}
}
}
}
如果数据成员 X
和 Y
的类型为 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;
}
在class定义中数据成员X
和Y
应该在数据成员矩阵
之前
private:
int X; // Matrix rows
int Y; // Matrix columns
int** matrix;
在这种情况下,您可以使用 mem-initializer 构造函数列表来初始化 class 数据成员。
例如
// 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];
}
}
}
}
并且您还应该定义复制赋值运算符或将其定义为已删除。
否则,当您尝试将 class 的一个对象分配给另一个对象时会出现问题。
考虑到函数 main 应具有 return 类型 int
int
main()
我需要帮助。现在我正在尝试制作一个 class 矩阵,但是我的程序在 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 From Moscow 所指出的,建议 delete
所有内存,因此您还应考虑添加 delete [] matrix
,以删除您要删除的一维指针数组使用 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];
}
}
}
}
如果数据成员 X
和 Y
的类型为 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;
}
在class定义中数据成员X
和Y
应该在数据成员矩阵
private:
int X; // Matrix rows
int Y; // Matrix columns
int** matrix;
在这种情况下,您可以使用 mem-initializer 构造函数列表来初始化 class 数据成员。
例如
// 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];
}
}
}
}
并且您还应该定义复制赋值运算符或将其定义为已删除。 否则,当您尝试将 class 的一个对象分配给另一个对象时会出现问题。
考虑到函数 main 应具有 return 类型 int
int
main()