2013-02-10 29 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-ree)。 – 2013-02-10 17:22:25

+0

@OliCharlesworth關於這個帖子的同樣的事情。 cgurleyuk,指針被複制到'std :: vector'中,所以這兩個對象都是'刪除'它。你應該爲緩衝區使用'std :: string' /'std :: vector '或者爲指針使用'std :: shared_ptr'。 – 2013-02-10 17:24:45

+0

考慮到它的用法,我會完全拋棄Record並只管理一個'std :: vector >'' – WhozCraig 2013-02-10 17:41:59

回答

1

這是一個Rule of three的情況。如果您的類需要釋放析構函數中的資源,通常需要聲明一個複製構造函數(和複製賦值運算符),以複製所擁有的資源,管理共享所有權或防止被複制。

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

該函數返回Record的副本。所以現在你有兩個Record s包含相同的m_bufRecord指針。在這些Record上運行析構函數會嘗試刪除兩次相同的指針值。