[英]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];
}
}
}
}
如果數據成員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;
}
在類定義中,數據成員X
和Y
應位於數據成員矩陣之前
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.