скажем, я создал собственный класс Array и у меня есть следующий конструктор:
Array::Array(size_t size)
{
mySize = size;
//myData is of type int*
myData = new int[mySize]; // this stuff is allocated on a heap
}
Насколько мне известно, конструктор копирования по умолчанию в этом случае будет реализован так:
Array::Array(Array& a)
{
mySize = a.mySize;
myData = a.myData; //points to the same memory on the heap
}
Наконец, скажем, у меня есть следующий код в моем файле main.cpp
int main()
{
Array a(1);
Array b(a); //copy constructor is invoked
}
То, что я ожидал, было утечкой памяти из-за удаления указателей myData в память свободного хранилища, НО у меня следующая ошибка времени выполнения:
*** glibc detected *** ./main.out: double free or corruption (fasttop): 0x086ad008 ***
ЗАЧЕМ? Кажется, что ~ Array () каким-то образом автоматически освобождает память, выделенную в куче, — но это очень противоречит мне. Может я что-то упустил?
ОБНОВИТЬ:
class Array{
private:
size_t mySize;
int *myData;
...
ОБНОВЛЕНИЕ 2:
main.cpp:
#include <iostream>
#include "array.h"
int main()
{
Array a(1);
Array b(a);
}
array.h:
#ifndef ARRAY_H_
#define ARRAY_H_
#include <stddef.h>
class Array{
private:
size_t mySize;
int *myData;
public:
Array(size_t size);
~Array();
void set(int i,int val);
int get(int i);
size_t getSize();
};
#endif
array.cpp:
#include "array.h"
Array::Array(size_t size)
{
mySize = size;
myData = new int[mySize];
}
Array::~Array()
{
delete[] myData;
}
void Array::set(int i, int val)
{
if(i>=0 && i<mySize)
myData[i] = val;
}
int Array::get(int i)
{
if(i>=0 && i<mySize)
return myData[i];
else return -1;
}
size_t Array::getSize()
{
return mySize;
}
Я думаю, что в вашем деструкторе у вас есть
Array::~Array(void)
{
delete [] myData; //points to the same memory on the heap
}
Проблема двойная бесплатная
Пример:
int main()
{
Array a(1); // here a.myData = 0x12345678
Array b(a); //copy constructor is invoked // here b.myData = 0x12345678
// pop stack (call destroy of object)
// delete b.myData
// delete a.myData already delete
}
Двухместный бесплатно
РЕДАКТИРОВАТЬ:
Для вашего копирования используйте конструктор const
потому что вы не изменяете.
Array::Array(const Array& a)
{
mySize = a.mySize;
myData = a.myData; //points to the same memory on the heap
}
Удачи !
Так что … несмотря на ваши претензии, оказывается, вы делать удалите массив в деструкторе, а конструктор копирования будет мелкой копией, поэтому вы получите двойное удаление. Просто.
Array::~Array()
{
delete[] myData;
}
Так как это динамический массив, он должен владеть данными, поэтому вы вправе удалить в деструкторе, но вам нужно «глубоко» скопировать в конструкторе копирования а также оператор присваивания. Увидеть правило трех.
Ваша копия является мелкой копией, поэтому ЕСЛИ у вас есть деструктор, который освобождает память, каждый объект пытается удалить ту же самую память.
Ты не иметь сделать мелкую копию. Вы можете написать свой собственный явный конструктор копирования, который копирует фактические данные во вновь выделенный массив.
Мне нравится предложение Google отключить конструкторы копирования и присваивания и предпочитаю явное CopyFrom()
методы.
«двойное освобождение» означает, что тот же указатель был дан delete[]
дважды. потому что в вашем деструкторе (предположительно) это delete[]
как в объекте a
а также b
, практическое решение: использовать std::vector
без необходимости не связывайтесь с необработанными массивами и т. д.
Я думаю, что ваши desctructors (из массива ‘a’ и ‘b’) пытаются освободить одну и ту же память (двойное освобождение). Может быть, вы должны проверить свои myData до освобождения.