2015-06-19 57 views
2

我測試了升壓ptr_containers和下面寫了一個小程序:爲什麼double free或corruption錯誤在運行時不會發生boost ptr_container?

class Test { 
    public: 
     ~Test() { 
      cout << "Test Destructor called" << endl; 
     } 
}; 

int main(int argc, char** argv) { 

    boost::ptr_map<int, Test> TestContainer; 
    boost::ptr_vector<Test> TestVector; 
    for (int i=0; i<2; ++i) { 
     Test* ptr = new Test(); 
     TestContainer.insert(i, ptr); 
     TestVector.push_back(ptr); 
    } 

} 

一旦我執行計劃「名爲Test析構函數」打印四個時間和程序成功完成。我期待打印將發生2次,然後「doube free ...」錯誤信息將被拋出。爲什麼在上述情況下不會發生這種情況,但是它發生在一個原始指針(Test *)上?

+5

如果您有意編寫調用未定義行爲的程序,然後什麼都可以預期,包括「工作」,轟然等 – PaulMcKenzie

+0

雙重釋放錯誤是不確定的行爲,未定義的行爲並不意味着「崩潰」(http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html),儘管崩潰是一個有效的結果。 –

+3

這是UB常見的誤解。未定義的行爲可能意味着*不可預知的行爲*。這就是爲什麼你無法預測行爲。 –

回答

1

ptr_mapptr_vector擁有自己的元素。

程序不正確。一次在兩個容器中插入相同的元素會導致雙重刪除。

刪除已刪除指針的行爲是未定義的。任何事情都可能發生。請參閱Undefined Behaviour

使用類似valgrind的工具來捕獲此信息。


如果您確實想知道,修復此示例的最簡單方法是對其中一個容器使用非擁有指針。一定要管理要素的相對壽命:

#include <boost/ptr_container/ptr_vector.hpp> 
#include <iostream> 
#include <map> 

class Test { 
    public: 
     ~Test() { 
      std::cout << "Test Destructor called" << std::endl; 
     } 
}; 

int main() { 

    boost::ptr_vector<Test> TestVector; 
    { 
     std::map<int, Test*> TestContainer; 

     for (int i=0; i<2; ++i) { 
      Test* ptr = new Test(); 
      TestContainer.emplace(i, ptr); 
      TestVector.push_back(ptr); 
     } 
    } 

} 
相關問題