2010-09-27 3 views
3

Я получаю сообщение об ошибке - куча коррупции, не могу понять, почему.Почему моя куча повреждена?

Моя база:

ч:

class Base 
{ 
public : 
    Base(char* baseName, char* cityName); 
    virtual ~Base(); 

    list<Vehicle*>::const_iterator GetEndList(); 
    void PrintAllVehicles(ofstream &ResultFile) const; 
    char* GetBaseName() const; 
    char* GetLocation() const; 
    void InsertNewVehicleToBase(Vehicle* newVehicle); 
    list<Vehicle*>::const_iterator FindVehicle(char* id); 
    void RemoveVehicle (list<Vehicle*>::const_iterator beg); 



private: 
    char* m_name; 
    char* m_location; 
    list<Vehicle*> m_baseVehicles; 

}; 

каст:

Base::Base(char* baseName, char* cityName) 
{ 
    m_name = new char [strlen(baseName)+1]; 
    strcpy(m_name, baseName); 
    m_location = new char [strlen(cityName)+1]; 
    strcpy(m_location, cityName); 
} 

Base::~Base() 
{ 
    delete [] m_name; 
    delete [] m_location; 
    //m_baseVehicles.clear(); 
} 

армии деструктор:

Army::~Army() 
{ 
    list<Base*>::iterator baseIter = m_basesList.begin(); 
    for (baseIter ; baseIter != m_basesList.end() ; ++baseIter) 
     delete (*baseIter); 
    m_basesList.clear(); 
} 

Что я делаю неправильно?

+2

Как заполняется m_basesList в первую очередь? – mkb

+0

Мы не можем сказать, если у нас нет компилируемого кода. –

+0

Как в стороне, почему вы используете char *, а не std :: string. – doron

ответ

7

Нет ничего явно неправильного в том, код, который вы указали, так что вероятность того, что ошибка указана в коде, который вы не показывали.

Самая непосредственная подозрительная вещь для меня заключается в том, что класс Base владеет двумя указателями и не имеет определенного конструктора или оператора присваивания. Это означает, что если вы когда-либо копируете объект Base, вы получите два объекта Base, указывающие на одни и те же данные, и когда они уничтожат, они будут удалять его дважды, вызывая повреждение кучи.

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

И наконец, вы не указали, где размещаются объекты Base. Возможно ли, что они передаются в объект Army, а также удаляются где-то за пределами объекта Army? Или, возможно, Base*, содержащиеся объектом Army, ссылаются на объекты в стеке, которые не следует удалять?

+1

Ваш второй пара помог мне найти мою ошибку: вы можете добавить к этому пункту: всякий раз, когда такой объект «Base» передается как параметр, он ДОЛЖЕН быть выполнен по ссылке (если не как указатель). В моем случае это была простая структура, которая была тривиально построена по копиям (и вы не хотите знать, где в моем коде появилась ошибка) thx dude :) – slashmais

1

Я не вижу проблем. Как сказал Мэтт Кейн, как он заселен?

1

Потери кучи происходят от копирования большего количества данных в выделенную ячейку кучи, чем память, выделенная ячейке. Начальные и конечные ячейки кучи содержат данные, чем при перезаписывании, будут сообщены как повреждение кучи.

Вы не разместили весь код, и я не вижу проблемы с кодом, который вы опубликовали, но я бы посоветовал использовать инструмент памяти, такой как Valgrind, чтобы помочь вам диагностировать проблему.

7

Видимые проблемы с этим кодом:

  • использование полукокса * не StD :: строка требует ручного управления памятью
  • Использование сырья указателей в STL контейнеры overcomplicates очистки код
  • использование CRT для струнных манипуляций a C++ 'code smell'
3

Вы не разместили часть кода, у которого есть проблема, потому что все это выглядит довольно нормально.Тем не менее, у него есть много константных-корректность задач:

Base(char* baseName, char* cityName); 

Строка должна быть передана в качестве const char*, если они не модифицируются.

virtual ~Base(); 

Не знаю, если это должно быть virtual; не может видеть, что такое его подклассы.

list<Vehicle*>::const_iterator GetEndList(); 

Должен быть константным методом, так как это const_iterator: list<Vehicle*>::const_iterator GetEndList() const;

char* GetBaseName() const; 
char* GetLocation() const; 

Они должен вернуться const char*, так как ваш код не настроен для обработки имени и местоположения меняются.

list<Vehicle*>::const_iterator FindVehicle(char* id); 

Опять же, должен быть константной метод: list<Vehicle*>::const_iterator FindVehicle(char* id) const;

Base::~Base() 
{ 
    delete [] m_name; 
    delete [] m_location; 
    //m_baseVehicles.clear(); 
} 

Вам не нужно m_baseVehicles.clear();, потому что это происходит в любом случае сразу после деструктора. Однако вам необходимо удалить транспортные средства, если они не указаны в другом месте, или вы получите утечку.

армии деструктор:

"деструктор". А где остальные Army?

Army::~Army() 
{ 
    list<Base*>::iterator baseIter = m_basesList.begin(); 
    for (baseIter ; baseIter != m_basesList.end() ; ++baseIter) 
     delete (*baseIter); 
    m_basesList.clear(); 
} 

Опять же, вам не нужно m_basesList.clear();.

5

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

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