2015-06-19 80 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); 
     } 
    } 

}