2013-05-10 3 views
0

У меня есть два простых класса. Все просто отлично, когда у меня есть пустой деструктор в классе A (пустой ~ A() {};). Когда я добавляю туда строки для освобождения массива, моя программа дает мне ошибку сегментации.Ошибка Seg при освобождении памяти в деструкторе

#include <iostream> 
#include <cstdlib> 
#include <ctime> 
using namespace std; 

class A 
{ 
    private : 

     int n; 
     int m; 
     int **array; 

    public : 

     A(); 
     A(int nn, int mm); 
     A(const A& a); 
     A& operator=(A a); 
     int getAt(int i, int j); 
     int getN(){return n;} 
     int getM(){return m;} 
     ~A(); 
}; 

A::A() 
{ 
    n = 0; 
    m = 0; 
    array = NULL; 
} 

A::A(int nn, int mm) 
{ 
    n = nn; 
    m = mm; 

    array = new int*[n]; 
    for(int i = 0; i <n; i++) 
     array[i] = new int[m]; 

    for(int i=0; i<n; i++) 
     for(int j=0; j<m; j++) 
      array[i][j] = rand()%2; 
} 

A::A(const A& a) 
{ 
    for(int i=0; i <n; i++) 
     delete[] array[i]; 
    delete [] array; 
    array = NULL; 

    n = a.n; 
    m = a.m; 

    array = new int*[n]; 
    for(int i = 0; i <n; i++) 
     array[i] = new int[m]; 

    for(int i=0; i<n; i++) 
     for(int j=0; j<m; j++) 
      array[i][j] = a.array[i][j]; 
} 

A& A::operator=(A a) 
{ 
    for(int i=0; i <n; i++) 
     delete[] array[i]; 
    delete [] array; 
    array = NULL; 

    n = a.n; 
    m = a.m; 

    array = new int*[n]; 
    for(int i = 0; i <n; i++) 
     array[i] = new int[m]; 

    for(int i=0; i<n; i++) 
     for(int j=0; j<m; j++) 
      array[i][j] = a.array[i][j]; 

    return *this; 
} 

int A::getAt(int i, int j) 
{ 
    return array[i][j]; 
} 

A::~A() 
{ 
    for(int i=0; i <n; i++) 
     delete[] array[i]; 
    delete [] array; 
    array = NULL; 
} 

class B 
{ 
    private : 

      A a; 

    public : 

      B(){} 
      B(A aa); 
      void setA(A aa); 
      void showA(); 
}; 

B::B(A aa) 
{ 
    a = aa; 
} 

void B::setA(A aa) 
{ 
    a = aa; 
} 

void B::showA() 
{ 
    int n = a.getN(); 
    int m = a.getM(); 

    for(int i=0; i<n; i++){ 
     for(int j=0; j<m; j++) 
      cout << a.getAt(i,j) << " "; 
     cout << "\n"; 
    } 
    cout << "\n"; 
} 

int main() 
{ 
    A a(3, 4); 
    B b(a); 

    b.showA(); 

    return 0; 
} 

Как это исправить? И почему это произошло?

РЕШИТЬ:

#include <iostream> 
#include <cstdlib> 
#include <ctime> 
using namespace std; 

class A 
{ 
    private : 

     int n; 
     int m; 
     int **array; 

    public : 

     A(); 
     A(int nn, int mm); 
     A(const A& a); 
     A& operator=(const A& a); 
     int getAt(int i, int j); 
     int getN(){return n;} 
     int getM(){return m;} 
     ~A(); 
}; 

A::A() 
{ 
    n = 0; 
    m = 0; 
    array = NULL; 
} 

A::A(int nn, int mm) 
{ 
    n = nn; 
    m = mm; 

    array = new int*[n]; 
    for(int i = 0; i <n; i++) 
     array[i] = new int[m]; 

    for(int i=0; i<n; i++) 
     for(int j=0; j<m; j++) 
      array[i][j] = rand()%2; 
} 

A::A(const A& a) 
{ 
    n = a.n; 
    m = a.m; 

    array = new int*[n]; 
    for(int i = 0; i <n; i++) 
     array[i] = new int[m]; 

    for(int i=0; i<n; i++) 
     for(int j=0; j<m; j++) 
      array[i][j] = a.array[i][j]; 
} 

A& A::operator=(const A& a) 
{ 
    for(int i=0; i <n; i++) 
     delete[] array[i]; 
    delete [] array; 
    array = NULL; 

    n = a.n; 
    m = a.m; 

    array = new int*[n]; 
    for(int i = 0; i <n; i++) 
     array[i] = new int[m]; 

    for(int i=0; i<n; i++) 
     for(int j=0; j<m; j++) 
      array[i][j] = a.array[i][j]; 

    return *this; 
} 

int A::getAt(int i, int j) 
{ 
    return array[i][j]; 
} 

A::~A() 
{ 
    for(int i=0; i <n; i++) 
     delete[] array[i]; 
    delete [] array; 
    array = NULL; 
} 

class B 
{ 
    private : 

      A a; 

    public : 

      B(){} 
      B(A aa); 
      void setA(A aa); 
      void showA(); 
}; 

B::B(A aa) 
{ 
    a = aa; 
} 

void B::setA(A aa) 
{ 
    a = aa; 
} 

void B::showA() 
{ 
    int n = a.getN(); 
    int m = a.getM(); 

    for(int i=0; i<n; i++){ 
     for(int j=0; j<m; j++) 
      cout << a.getAt(i,j) << " "; 
     cout << "\n"; 
    } 
    cout << "\n"; 
} 

int main() 
{ 
    A a(3, 4); 
    B b(a); 

    b.showA(); 

    return 0; 
} 
+1

Вам необходимо определить ваш выигранный экземпляр копирования и оператор присваивания, которые будут делать правильные действия с массивом. См. Http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three –

+0

Вам необходимо следовать [правилу из трех] (http://en.wikipedia.org/wiki/Rule_of_three_% 28C% 2B% 2B_programming% 29). – juanchopanza

+0

@LightnessRacesinOrbit: не для меня. Добавлен экземпляр-конструктор и оператор присваивания классу A, но все еще имеет ошибку seg. – yak

ответ

2

Ваш конструктор копий сначала перезаписывает старый n новым n, а затем пытается удалить элементы старого массива n. Но что, если массивы имеют разные размеры? Перезаписать nпосле петля.

Или, еще лучше, избавитесь от этого страшного чудовища и используйте вместо него std::vector.

+0

Хм, ничего не изменилось. Запустите valgrind: http://pastie.org/private/gvbtdoqmotwc2fi1bjweg. Все еще не знаете, где проблема, изменили то, что вы сказали, но все же - seg fault. – yak

1

Во-первых, вы нарушаете «правило трех» (в любом классе, который выделяет память, вам нужно иметь конструктор копирования и оператор присваивания, что «сделки» с выделенной памяти соответствующим образом).

Ваш деструктор также разрушен в случае, когда «массив» равен NULL - вам нужно проверить, что массив не равен NULL, прежде чем запускать цикл, чтобы удалить внутренние части.

Смежные вопросы