2014-12-11 6 views
-1

내 C++ 코드를 작성하는 동안 이상한 상황에 직면했습니다. 내 코드 안에는 C이라는 매트릭스 객체가 있습니다. C은 행렬 AB의 합과 같습니다. A+B의 값은 operator+을 통해 계산됩니다. C의 삶이 끝나면 나는 invalid pointer error과 맞닥뜨린 다.munmap_chunk 연산자와 파괴자가 호출 될 때 무효 포인터

이 내 전체 코드입니다 :

#include <iostream> 
#include <vector> 
using namespace std; 

class CMatrix 
{ 
private: 
    int rows=0,columns=0; 
    int **members=NULL; 
    void allocate(int rows,int columns); 
public: 
    CMatrix(int rows,int columns); 
    CMatrix(int rows,int columns,vector<vector<int>> clone); 
    CMatrix(const CMatrix& clone); 
    ~CMatrix(); 
    void print(); 
    void sum(const CMatrix &A,const CMatrix &B); 
    CMatrix operator+(const CMatrix &B); 
}; 

void CMatrix::allocate(int rows,int columns) 
{ 
    this->rows=rows; 
    this->columns=columns; 
    members=new int*[rows]; 
    for(int i=0;i<columns;i++) 
     members[i]=new int[columns]; 
} 

CMatrix::CMatrix(const CMatrix& clone) 
{ 
    allocate(clone.rows,clone.columns); 
    for(int i=0;i<rows;i++) 
     for(int j=0;j<columns;j++) 
      members[i][j]=clone.members[i][j]; 
} 

CMatrix::CMatrix(int rows,int columns) 
{ 
    allocate(rows,columns); 
} 

CMatrix::CMatrix(int rows,int columns,vector<vector<int>> clone) 
{ 
    allocate(rows,columns); 
    for(int i=0;i<rows;i++) 
     for(int j=0;j<columns;j++) 
      members[i][j]=clone[i][j]; 
} 

CMatrix::~CMatrix() 
{ 
    for(int i=0;i<rows;i++) 
     delete [] members[i]; 
    delete [] members; 
} 

void CMatrix::print() 
{ 
    cout<<"["<<endl; 
    for(int i=0;i<rows;i++) 
    { 
     for(int j=0;j<columns;j++) 
      cout<<members[i][j]<<(j==columns-1?"":",\t"); 
     cout<<endl; 
    } 
    cout<<"]"<<endl; 
} 

void CMatrix::sum(const CMatrix &A,const CMatrix &B) 
{ 
    // at this point, all matrices must have the same dimention 
    for(int i=0;i<rows;i++) 
     for(int j=0;j<columns;j++) 
      members[i][j]=A.members[i][j]+B.members[i][j]; 
} 

CMatrix CMatrix::operator+(const CMatrix &B) 
{ 
    CMatrix result(rows,columns); 
    result.sum(*this,B); 
    return result; 
} 

int main() 
{ 
    CMatrix A(3,3,{{1,2,3},{4,5,6},{7,8,9}}); 
    CMatrix B(3,3,{{3,4,-1},{7,-2,1},{3,2,-4}}); 
    CMatrix C(3,3); 
    cout<<"A is:"<<endl; 
    A.print(); 
    cout<<"B is:"<<endl; 
    B.print(); 
    cout<<"C=A+B is:"<<endl; 
    C=A+B; 
    C.print(); 
    return 0; 
} 

내가 잘못된 결과 유효하지 않은 포인터 오류에 직면 내 코드를 실행 :

A is: 
[ 
1, 2, 3 
4, 5, 6 
7, 8, 9 
] 
B is: 
[ 
3, 4, -1 
7, -2, 1 
3, 2, -4 
] 
C=A+B is: 
[ 
0, 0, 33 
17019120, 0, 7 
17019408, 0, 5 
] 
*** Error in `./a.out': munmap_chunk(): invalid pointer: 0x000000000103b230 *** 
Aborted (core dumped) 

어떻게 그것을 해결하기 위해?

$ valgrind --tool=memcheck --db-attach=yes ./a.out 
==11847== Memcheck, a memory error detector 
==11847== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. 
==11847== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info 
==11847== Command: ./a.out 
==11847== 
A is: 
[ 
1, 2, 3 
4, 5, 6 
7, 8, 9 
] 
B is: 
[ 
3, 4, -1 
7, -2, 1 
3, 2, -4 
] 
C=A+B is: 
[ 
==11847== Invalid read of size 8 
==11847== at 0x400FEE: CMatrix::print() (test.cpp:64) 
==11847== by 0x401655: main (test.cpp:96) 
==11847== Address 0x5a1d910 is 0 bytes inside a block of size 24 free'd 
==11847== at 0x4C2C83C: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==11847== by 0x400F7D: CMatrix::~CMatrix() (test.cpp:55) 
==11847== by 0x401646: main (test.cpp:95) 
==11847== 
==11847== 
==11847== ---- Attach to debugger ? --- [Return/N/n/Y/y/C/c] ---- 

NRVO가 제대로 구현되지 않은 것 같다

은 다시 내가 Valgrind의 사용하여 프로그램을 실행! 무엇을해야합니까?

참고 : 내가 사용하여 컴파일 : g++ -g -std=c++11 test.cpp

편집 : 코드의이 부분을 추가는

문제를 해결하지만 내 프로그램에 부담을 추가합니다. NRVO의 이점을 어떻게 누릴 수 있습니까? 모든

void CMatrix::operator=(const CMatrix &B) 
{ 
    for(int i=0;i<rows;i++) 
     for(int j=0;j<columns;j++) 
      members[i][j]=B.members[i][j]; 
} 
+0

@PiotrS. 나는 NRVO가 내 코드에 적용되었다고 가정했다. – barej

답변

0

먼저 당신의 사고를 가지고 당신의 "할당() : 당신은 '내가 < 행'대신 '내가 < 열'을 확인해야합니다. NRVO 정보 : 반환 값 최적화를 사용하려면 std = C++ 11을 지정할 필요가 없습니다. 당신은 당신이 최적화가 완벽하게 수행 볼 생성자/소멸자 일부 로깅을 추가하면 활성화하기 위해 당신은 일부

CMatrix D=A+B 

대신

C=A+B. 

을 넣어해야합니다. C는 다른 매개 변수와 함께 이전에 만들어 졌으므로 복사 생성자가없는 다른 개체로 초기화 할 수 없습니다.