2015-04-12 3 views
-1

Я пытаюсь выяснить утечки памяти, которые у меня есть.Утечка памяти с производным классом

я эти (упрощенные) классы (не может быть изменен, я должен работать с ними):

class Base 
{ 
bool baseBool; 
Base(Base&){}; 
virtual ~Base(); 
} 

class Derived1 : public: Base 
{ 
char* text; 
Derived1(Derived1&); 
~Derived1(); 
} 

class Derived2 : public: Base 
{ 
int num; 
Derived2(Derived2&); 
~Derived() 
} 

Derived1 Copy конструктор

Derived1::Derived1(Derived1& derived):text("") 
{ 
    text=new char[strlen(text)+1]; //assign enough memory + 1 
    strcpy(text,derived.text); //copy existing aText into new objects aText 
} 

Тогда У меня есть структура используется для манипулирования их

struct Container 
{ 
Container& operator=(Container&); 
Base** bases 
} 

В перегруженном операторе = для структуры Контейнер Я делаю глубокую копию Контейнерные объекты. Как так:

Container& Container::operator=(Container& R) 
{ 
    int i,j,k; 
    for(i=0;i<MAX;i++) 
     delete bases[i]; 
    delete[]bases; 
    bases=new Base*[MAX]; 
    for(j=0;j<MAX;j++) 
     answers[j]=0; 
    for(k=0;k<MAX;k++) 
    { 
     if(dynamic_cast<Derived1 *>(R.bases[k])) 
      bases[k]=new Derived1(*(dynamic_cast<Derived1 *>(R.bases[k]))); 
     else 
      bases[k]=new Derived2(*(dynamic_cast<Derived2 *>(R.bases[k]))); 
    } 
    return *this; 
} 

Эта часть кода работает, если я назначить вновь созданный объект контейнера, используя перегруженный оператор =

Как и в моей основной

Container containers[2]; 
bases = new Base*[2]; 
bases[0] = new Derived1("boooo"); 
bases[1] = new Derived2(3); 
containers[0]=*(new Container(bases)); //uses the overloaded operator= OK 

Но если я должны были назначить два уже сделанных объекта контейнера друг другу следующим образом:

containers[0]=containers[1]; 

Следующий отладки он выходит из строя на

for(i=0;i<MAX;i++) 
delete bases[i]; 

Высказывание

HEAP[ass3.exe]: Heap block at 00729268 modified at 00729295 past requested size of 25 
ass3.exe has triggered a breakpoint. 
HEAP[ass3.exe]: Invalid address specified to RtlValidateHeap(00720000, 00729270) 
ass3.exe has triggered a breakpoint. 

Вот почему я думаю, что у меня есть утечки памяти, потому что Derived1 имеет символ *.

Рад за любой вход.

Спасибо! Я надеюсь, что я был достаточно ясным ...

Редактировать: У меня есть пустой конструктор основной копии, и производный cc также существует. Может быть, я пошел на простой пример.

+2

Ugh Я не сомневаюсь, что у вас есть утечки памяти. Вот почему C++ был * изобретен *. Использовать 'std :: vector' –

+1

Вы также реализовали собственный конструктор копирования? –

+0

1) Ваш базовый класс должен иметь виртуальный деструктор. 2) Вы не реализовали конструктор копирования. – PaulMcKenzie

ответ

0

Похоже, что MAX является числом, большим, чем размер оснований, т.е. базы могут иметь только 5 записей, в то время как MAX может быть 10. В этом случае, как только вы закончите конец баз (базы [5] не существуют, если размер составляет всего 5, потому что нумерация начинается с 0). Я обычно использую вектор вместо массив и мой код для цикла будет выглядеть следующим образом:

for(i=0;i<bases.size();i++) 
delete bases[i]; 

Это гарантирует, что ваш цикл не проходит мимо конца оснований.

+0

Спасибо за ввод, но он падает на самой первой итерации. Как я уже сказал, это отлично работает, если я использую operator = для нового объекта Container. См. Мой обновленный OP. – cppStud

0

Из примера, вы указали, что вам необходимо убедиться, что элемент «основы» структуры Container фактически назначен и инициализирован.

Из выраженных вами симптомов (сбой на первой итерации), похоже, что вы удаляете неинициализированный указатель базиса (массив указателей), или сами фактические указатели неправильно инициализируются инициализацией nullptr.

Это может быть, если ваш образец кода является неполным.