2013-02-10 2 views
-1

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

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

Пожалуйста, прочитайте [Правило трех] (http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three). –

+0

@OliCharlesworth О записи то же самое. cgurleyuk, указатель копируется в 'std :: vector', поэтому оба объекта« удаляют »его. Вы должны использовать 'std :: string' /' std :: vector 'для буфера или' std :: shared_ptr' для указателя. –

+0

Учитывая его использование, я бы полностью загрузил запись и просто управлял 'std :: vector >' – WhozCraig

ответ

1

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

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

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