【问题标题】:Error deleting a multidimensional matrix删除多维矩阵时出错
【发布时间】:2012-10-20 09:32:33
【问题描述】:

使用此析构函数删除多维矩阵时:

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++ matrix new-operator glibc delete-operator


【解决方案1】:

当您有一个分配内存的对象时,只需要注意该对象的复制方式。您需要定义一个复制构造函数和一个赋值运算符,以根据您的对象分配的内存来做正确的事情。否则在删除对象时会出错,通常是因为您最终删除了两次相同的内存。

您似乎没有定义复制构造函数或赋值运算符。当你定义一个析构函数时,你几乎总是需要定义一个复制构造函数和一个赋值运算符。这被称为“三法则”。您可以在此处查看有关如何执行此操作的一些指南(或者只是阅读一本好的 C++ 书籍)。

What is The Rule of Three?

【讨论】:

  • 定义复制构造函数后,我得到了同样的错误,但 valgrind 现在说错误在析构函数中。
  • 为了帮助解决这个问题,我真的需要看一个完整的程序。您能否将您的代码缩减为仍然存在错误的尽可能小的版本,然后发布整个代码。或者,如果您不确定您的复制构造函数是否正确,那么您可以发布它。如果您确定您已经被告知这一点,但是人们说使用 std::vector 而不是自己分配内存的原因是,正如您所发现的那样,自己分配内存很难。
  • 即使在您发布的新代码中也没有复制构造函数。
  • 您添加的是赋值运算符。您还需要一个复制构造函数。您的 operator* 函数在返回矩阵时调用复制构造函数。我希望它是导致您崩溃的复制构造函数(或缺少它)。
【解决方案2】:

没有看到更多代码,我只能猜测您可能会

  • 没有正确的复制构造函数,因此 user_matrix 指针被复制,或者
  • 默认构造函数没有初始化成员user_matrix,或者
  • matrix_mult 返回一个无效的指针。

但至少有一件事是错误的。 temp.user_matrix 在 temp.user_matrix=...之前被删除。

【讨论】:

  • "temp.user_matrix 被删除之前 temp.user_matrix=" 怎么样?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-04-25
  • 2017-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多