Ошибка удаления многомерной матрицы

При удалении многомерной матрицы этим деструктором:

matrix::~matrix(){
int i;
for(i=0;i<n;i++){
delete[] user_matrix[i];}
delete[] user_matrix;}

Я воскрешаю эту ошибку:

*** glibc detected *** ./a.out: free(): invalid pointer: 0x00007fdb33067778 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7eb96)[0x7fdb32d2db96]
./a.out[0x40157c]
./a.out[0x40172b]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7fdb32cd076d]
./a.out[0x400b09]

Далее следует «карта памяти». Когда я запускаю его через valgrind, это говорит о том, что в операторе перегружена ошибка для *:

  matrix matrix::operator* (matrix param) {
//n is the size of the square matrix
if(n!=param.n){
//returns an empty matrix if they are not of equal size
matrix blah;
return blah;}
//initiates a nxn matrix that is empty
matrix temp(n,0);
temp.user_matrix=matrix_mult(user_matrix,param.user_matrix);
return temp;}

Это согласуется с вызываемым деструктором, а также с закомментированным деструктором, он работает до тех пор, пока у компьютера не кончится память или вычисления не станут достаточно маленькими и завершатся.

#include"matrix.h"using namespace std;

matrix::matrix(int n1,int initiate){
srand(3534.34535);
n=n1;
//float** user_matrix
user_matrix=new float* [n];
int i;
for(i=0;i<n;i++){
user_matrix[i]=new float [n];}

if(initiate==1){

int j;
for(i=0;i<n;i++){

for(j=0;j<n;j++){

cout<<"please ["<<i<<"]["<<j<<"]"<<endl;

cin>>user_matrix[j][i];}
}
}else if(initiate==2){
user_matrix=random_matrix(n);}

}

float** matrix::inverse(){
int i,k;
float sub_det,detin;

detin=det();

if(detin==0){cout<<"uninvertable"<<endl;};

float** inverse = new float* [n];
for(i=0;i<n;i++){
inverse[i]=new float [n];}

float invertdet=1.0/detin;

for(i=0;i<n;i++){
for(k=0;k<n;k++){
inverse[k][i]=invertdet*pow(-1,i+k)*determinant(sub_matrix(user_matrix,i,k,n),n-1);
}
}

return inverse;}

void matrix::display(){
//cout<<"lol"<<endl<<n<<endl;
int i,j;
cout.precision(5);
for(j=0;j<n;j++){
cout<<"|";
for(i=0;i<n;i++){

cout<<user_matrix[i][j]<<"   ";};cout<<"|";
cout<<endl<<endl;}
cout<<endl<<endl;
}

float matrix::determinant(float** matrix,int n1){
if(n1==1){return matrix[0][0];}
int i;
float det1=0;
i=0;
for(i=0;i<n1;i++){
float** temp_matrix=sub_matrix(matrix,i,0,n1);
det1 = det1 + pow(-1.0,i)*matrix[i][0]*determinant(temp_matrix,n1-1);
int j=0;
for(j=0;j<n1-1;j++){delete[] temp_matrix[j];}
delete[] temp_matrix;
}
return det1;}

float matrix::det(){return determinant(user_matrix,n);}float** matrix::sub_matrix(float** matrix,int colum,int row,int n){
float **sub_matrix=new float *[n-1];
int iter;

for(iter=0;iter<(n-1);iter++){
sub_matrix[iter]=new float [n-1];}
int iter2;
int placeholder1,placeholder2;

placeholder1=placeholder2=0;

for(iter=0;iter<n;iter++){

if(iter==colum){continue;}
placeholder2=0;
for(iter2=0;iter2<n;iter2++){
if(iter2==row){continue;}
sub_matrix[placeholder1][placeholder2]=matrix[iter][iter2];
placeholder2++;
}
placeholder1++;

}

return sub_matrix;}

float** matrix::random_matrix(int n){

int i,j;
float** temp_mat=new float* [n];
for(i=0;i<n;i++){
temp_mat[i]=new float [n];}

for(i=0;i<n;i++){
for(j=0;j<n;j++){
temp_mat[i][j]=rand()%10 +1;}
}
return temp_mat;}

float** matrix::matrix_mult(float** matrix1,float** matrix2){
int i,j,k;
float subresult;
float** ret_mat;
ret_mat=new float* [n];
for(i=0;i<n;i++){
ret_mat[i]=new float [n];}
for(i=0;i<n;i++){
for(j=0;j<n;j++){

for(k=0;k<n;k++){
subresult=subresult + matrix1[k][i]*matrix2[j][k];
}
ret_mat[i][j]=subresult;}
}
return ret_mat;}
matrix::~matrix(){
int i;for(i=0;i<n;i++){delete[] user_matrix[i];};delete[] user_matrix;}

matrix matrix::operator* (matrix param) {
if(n!=param.n){
matrix blah;
return blah;}

matrix temp(n,0);
temp.user_matrix=matrix_mult(user_matrix,param.user_matrix);
return temp;}

int main(){
int i;
/*for(i=1;i<20;i++){
matrix m1(i,2);
cout<<i<<" "<<m1.det()<<endl;}*/
matrix m1(16,2),m2(16,2),m3(16,0);
for(i=0;i<100000;i++){m3=m1*m2;}return 0;}

Код без функций, не вызывающих ошибок.

#include"matrix.h"using namespace std;

matrix::matrix(int n1,int initiate){
srand(3534.34535);
n=n1;
//float** user_matrix
user_matrix=new float* [n];
int i;
for(i=0;i<n;i++){
user_matrix[i]=new float [n];}

if(initiate==1){

int j;
for(i=0;i<n;i++){

for(j=0;j<n;j++){

cout<<"please ["<<i<<"]["<<j<<"]"<<endl;

cin>>user_matrix[j][i];}
}
}else if(initiate==2){
user_matrix=random_matrix(n);}

}

float** matrix::random_matrix(int n){

int i,j;
float** temp_mat=new float* [n];
for(i=0;i<n;i++){
temp_mat[i]=new float [n];}

for(i=0;i<n;i++){
for(j=0;j<n;j++){
temp_mat[i][j]=rand()%10 +1;}
}
return temp_mat;}

float** matrix::matrix_mult(float** matrix1,float** matrix2){
int i,j,k;
float subresult;
float** ret_mat;
ret_mat=new float* [n];
for(i=0;i<n;i++){
ret_mat[i]=new float [n];}
for(i=0;i<n;i++){
for(j=0;j<n;j++){

for(k=0;k<n;k++){
subresult=subresult + matrix1[k][i]*matrix2[j][k];
}
ret_mat[i][j]=subresult;}
}
return ret_mat;}
matrix::~matrix(){
int i;for(i=0;i<n;i++){delete[] user_matrix[i];};delete[] user_matrix;}

matrix matrix::operator* (matrix param) {
if(n!=param.n){
matrix blah;
return blah;}

matrix temp(n,0);
temp.user_matrix=matrix_mult(user_matrix,param.user_matrix);
return temp;}

matrix & matrix::operator= (const matrix & param)
{
int i,j;
float** new_array=new float* [param.n];
for(i=0;i<param.n;i++){
new_array[i]=new float [param.n];}
for(i=0;i<param.n;i++){
for(j=0;j<param.n;j++){
new_array[i][j]=param.user_matrix[i][j];}
}

for(i=0;i<param.n;i++){
delete[] user_matrix[i];}
delete[] user_matrix;
user_matrix=new_array;
n=param.n;
return *this;

}

int main(){
int i;
matrix m1(16,2),m2(16,2),m3(16,0);
for(i=0;i<100000;i++){m3=m1*m2;}return 0;}

0

Решение

Когда у вас есть объект, который выделяет память, просто нужно быть осторожным с тем, как этот объект копируется. Вам нужно определить конструктор копирования и оператор присваивания, которые правильно делают с точки зрения памяти, выделяемой вашим объектом. В противном случае вы получите ошибку при удалении объектов, обычно потому, что в итоге вы удаляете одну и ту же память дважды.

Похоже, вы не определили конструктор копирования или оператор присваивания. Когда вы определяете деструктор, вам почти всегда нужно определять конструктор копирования и оператор присваивания. Это известно как «правило трех». Вы можете посмотреть здесь некоторые рекомендации о том, как это сделать (или просто прочитать хорошую книгу по C ++).

Что такое правило трех?

1

Другие решения

Не видя больше кода, я могу только догадываться, что вы можете

  • не иметь надлежащего конструктора копирования, поэтому указатель user_matrix копируется, или
  • конструктор по умолчанию не инициализирует член user_matrix, или
  • matrix_mult возвращает неверный указатель.

Но, по крайней мере, одна вещь не так. temp.user_matrix удаляется перед temp.user_matrix = …

0

По вопросам рекламы [email protected]