Ошибка двойного освобождения при выполнении после удаления указателя в деконструкторе

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

class Record {
public:
Record(unsigned short numBytes, char* bufRecord);
~Record();

unsigned short size() {return m_numBytes;}
private:
unsigned short m_numBytes;
char* m_bufRecord;
};

Record::Record(unsigned short numBytes, char* bufRecord) {
m_numBytes = numBytes;
m_bufRecord = new char[numBytes];

for(unsigned short i=0; i<numBytes; i++)
m_bufRecord[i] = bufRecord[i];
}

Record::~Record() {
delete m_bufRecord;
}

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

class File {
public:
File(const char* fileName);
~File();

unsigned int numRecords() {return m_records.size();}
Record getRecord(unsigned int numRecord) {return m_gdsRecords[numRecord];}
private:
std::ifstream           m_file;
std::vector<Record>     m_records;
};

File::File(const char* fileName) : m_file(fileName, ios::in | ios::binary) {
while(!m_file.eof()) {
char bufNumBytes[2];
char* bufRecord;
unsigned short numBytes;

m_file.read(bufNumBytes, 2);
numBytes = (bufNumBytes[0] << 8) + bufNumBytes[1] - 2;
bufRecord = new char[numBytes];
m_file.read(bufRecord, numBytes);

Record record(numBytes, bufRecord);
m_records.push_back(record);

delete bufRecord;
}
}

Однако, когда я создаю экземпляр этого класса, я получаю следующую ошибку, которая, кажется, утверждает, что я дважды освобождаю m_bufRecord:

*** Error in `./a.out': double free or corruption (fasttop): 0x0000000001cb3280 ***

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

-1

Решение

Это случай Правило трех. Если вашему классу необходимо освободить ресурсы в деструкторе, ему, как правило, необходимо объявить конструктор копирования (и оператор назначения копирования), чтобы либо скопировать принадлежащий ресурс, либо управлять общим владением, либо предотвратить копирование.

1

Другие решения

Record getRecord(unsigned int numRecord) {return m_gdsRecords[numRecord];}

Эта функция возвращает копию Record, Итак, теперь у вас есть два Recordс тем же m_bufRecord указатель. Запуск деструкторов на этих Records попытается удалить одно и то же значение указателя дважды.

0

По вопросам рекламы [email protected]