0

このデストラクタで多次元行列を削除する場合:

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;}
4

2 に答える 2

1

メモリを割り当てるオブジェクトがある場合、そのオブジェクトがどのようにコピーされるかに注意する必要があります。オブジェクトが割り当てるメモリに関して正しいことを行うコピー コンストラクターと代入演算子を定義する必要があります。そうしないと、オブジェクトを削除するときにエラーが発生します。これは、通常、同じメモリを 2 回削除することになるためです。

コピー コンストラクターまたは代入演算子を定義していないようです。デストラクタを定義するときは、ほとんどの場合、コピー コンストラクタと代入演算子も定義する必要があります。これは「3 のルール」として知られています。これを行う方法に関するガイドラインについては、こちらを参照してください (または、優れた C++ の本を読んでください)。

3つのルールとは?

于 2012-10-20T09:53:16.307 に答える
0

これ以上コードを見ない限り、私はあなたがそうかもしれないと推測することしかできません

  • 適切なコピー コンストラクターがないため、user_matrix ポインターがコピーされる、または
  • デフォルトのコンストラクターがメンバー user_matrix を初期化しない、または
  • matrix_mult は無効なポインターを返します。

しかし、少なくとも 1 つのことが間違っています。temp.user_matrix は temp.user_matrix=... の前に削除されます

于 2012-10-20T09:52:15.767 に答える