我需要帮助。现在我正在尝试创建一个类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();
}
`
功能&#34; ShowMatrixOnScreen&#34;打印矩阵&#34; x&#34;在屏幕上,然后控制台冻结。
答案 0 :(得分:7)
你的析构函数有声明
Template.myTemplate.events({
'click #btnEditPhoto': function(event, template) {
$('.profilePhotoFile').click();
},
'change .profilePhotoFile': function(event, template) {
if (!event.target.files || event.target.files.length === 0) {
return;
} else {
var $inputImage = $(event.target);
var URL = window.URL || window.webkitURL;
var file = event.target.files[0];
var blobURL = URL.createObjectURL(file);
$image = $('#cropper > img');
$('#cropper-modal').modal();
$('#cropper-modal').on('shown.bs.modal', function() {
$image.cropper({
aspectRatio: 1.0,
autoCropArea: 1.0
}).cropper('replace', blobURL);
$inputImage.val('');
}).on('hidden.bs.modal', function() {
$image.cropper('destroy');
URL.revokeObjectURL(blobURL); // Revoke url
});
}
},
'click #btnSavePhoto': function(event, template) {
$image = $('#cropper > img');
//Change the width and height to your desired size
var base64EncodedImage = $image.cropper('getCroppedCanvas', {width: 10, height: 10}).toDataURL('image/jpeg');
$('#cropper-modal').modal('hide');
var newImage = new FS.File(base64EncodedImage);
Images.insert(newImage, function(err, fileObj) {
if (err) {
console.log(err);
} else {
//do something after insert
}
});
},
'click #btnCancel': function(event, template) {
$('#cropper-modal').modal('hide');
}
});
delete[] matrix[X];
不存在,因此您释放未分配给您的内存,即未定义的行为。它应该是matrix[X]
!
此外,正如Vlad From Moscow所指出的那样,delete [] matrix[i]
所有内存都是可取的,所以你还应该考虑添加delete
来删除你分配的1-D指针数组delete [] matrix
答案 1 :(得分:2)
问题是您的析构函数无效
首先在这个循环中
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
时,thsi循环才有效。因此,在循环之前,您必须检查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;
应位于数据成员矩阵之前
// 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;
}
}
}
}
在这种情况下,您可以使用mem-initializer构造函数列表来初始化类数据成员。
例如
// 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];
}
}
}
}
反过来,复制构造函数可以定义为
int
您还应该定义复制赋值运算符或将其定义为已删除。 否则,当您尝试将该类的一个对象分配给另一个对象时会出现问题。
考虑到函数main应具有返回类型int
{{1}} main()