Я пишу повторно массивный класс массива (std :: vector), как упражнение, используя ручные указатели (потому что я хочу знать, как они работают, прежде чем я начну использовать интеллектуальные указатели). Однако Valgrind сообщает об утечке памяти в функции checkMax().Утечка памяти; когда удаленное исключение поднято
template <typename T>
class Array{
public:
Array() : len(0),maxLen(1){
array=new T[maxLen];
// ........
}
Array(unsigned length, T&content=0) : len(length),maxLen(length*2){
array=new T[maxLen];
//..............
}
~Array(){
//delete[] array;
}
//..............
void push_back(const T& content){
checkMax();
// do stuff...
}
private:
T* array;
unsigned int len;
unsigned int maxLen;
..
void checkMax(){
if(len==maxLen){
//allocate more memory for the array
maxLen*=2;
T*temp=new T[maxLen]; // ------------- MEMORY LEAK HERE -------------
for(unsigned int i=0; i<len; i++){
temp[i]=array[i];
}
delete [] array;
array=temp;
}
}
};
Я разместил здесь только код, относящийся к памяти.
Я не понимаю, почему Valgrind сообщает об утечке памяти по указанной строке. Я удаляю старый массив после копирования старого содержимого массива в расширенный массив, две строки позже.
Кроме того, если я не комментирую функцию delete [] в деструкторе, я получаю исключение double free or corruption
, а Valgrind сообщает о недопустимом удалении (подразумевая повторное удаление), поэтому я полностью смущен. Любые идеи?
EDIT: Благодарим за ответы на вопросы! Прочитав комментарии, я обнаружил, что проблема связана не с моим классом, а с другой функцией, которую я вызывал с классом Array в качестве аргумента. Если я удалю вызов этой функции и добавит вызов удаления в класс, утечки памяти не произойдет. Вот моя функция:
template <typename T>
void printContents(Array<T> ar){
for(unsigned int i=0; i<ar.size(); i++){
cout<<"Content at i in array = " << ar.at(i) << endl;
}
}
После прочтения Правило трех (спасибо Крису) и ответ, отправленный Grizzly, я теперь понял, почему удалять [] недействителен. Из-за того, что я не перегрузил конструктор копирования, произошло мелкое копирование, из-за чего мой указатель массива получил , назначенный указателю в ar, а когда ar, когда он вышел из области действия, вызывается delete [], тем самым основная функция недействительна. Следовательно, я получал исключение. Если бы я удалил удаление, тогда массив, очевидно, останется выделенным и приведет к утечке памяти.
Спасибо за помощь, я проголосовал за ответ Гризли как правильный.
http: // stackoverflow.com/questions/4172722/what-is-the-rule-of-three – chris
Чтобы разработать правило трех комментариев, копируете ли вы из одного массива в другой, что может привести к двойному удалению? –
@chris Да, это было то, о чем я тоже думал. Сумант, вы передаете «Массив» по значению в качестве параметра в любом месте или создаете копии по-другому? У вас есть конструктор копирования, который правильно обрабатывает указатель 'array'? Если вам не хватает конструктора копирования, поведение по умолчанию было бы просто скопировать указатель, а это значит, что у вас есть два указателя на один и тот же «массив», следовательно, двойное удаление. – wilsonmichaelpatrick