При удалении многомерной матрицы этим деструктором:
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;}
Когда у вас есть объект, который выделяет память, просто нужно быть осторожным с тем, как этот объект копируется. Вам нужно определить конструктор копирования и оператор присваивания, которые правильно делают с точки зрения памяти, выделяемой вашим объектом. В противном случае вы получите ошибку при удалении объектов, обычно потому, что в итоге вы удаляете одну и ту же память дважды.
Похоже, вы не определили конструктор копирования или оператор присваивания. Когда вы определяете деструктор, вам почти всегда нужно определять конструктор копирования и оператор присваивания. Это известно как «правило трех». Вы можете посмотреть здесь некоторые рекомендации о том, как это сделать (или просто прочитать хорошую книгу по C ++).
Не видя больше кода, я могу только догадываться, что вы можете
Но, по крайней мере, одна вещь не так. temp.user_matrix удаляется перед temp.user_matrix = …