【问题标题】:ptr_vector is not freed properlyptr_vector 未正确释放
【发布时间】:2012-08-15 15:18:06
【问题描述】:

我正在尝试使用 ptr_vector 来存储一些指针,但我在使用 main 方法时立即收到错误消息。 这是我的代码:

int main(void)
{
    boost::ptr_vector<string> temp;
    string s1 = "hi";
    string s2 = "hello";
    temp.push_back(&s1);
    temp.push_back(&s2);
    return 0;
}

这是我收到的错误消息:

Critical error detected c0000374
Windows has triggered a breakpoint in Path_Tree.exe.

This may be due to a corruption of the heap, which indicates a bug in Path_Tree.exe or     any of the DLLs it has loaded.

This may also be due to the user pressing F12 while Path_Tree.exe has focus.

The output window may have more diagnostic information.
The program '[7344] Path_Tree.exe: Native' has exited with code 0 (0x0).

我做错了什么? 谢谢!

【问题讨论】:

    标签: c++ boost ptr-vector boost-ptr-container


    【解决方案1】:

    ptr_vector 拥有你给它的指针所指向的对象的所有权(这意味着当它完成这些指针时,它会在这些指针上调用delete)。如果您只想要一个指针向量,请使用:

    int main()
    {
        std::vector<string*> temp;
        //s1 and s2 manage their own lifetimes
        //(and will be destructed at the end of the scope)
        string s1 = "hi";
        string s2 = "hello";
        //temp[0] and temp[1] point to s1 and s2 respectively
        temp.push_back(&s1);
        temp.push_back(&s2);
        return 0;
    }
    

    否则,您应该使用 new 分配字符串,然后 push_back 结果指针:

    int main()
    {
        boost::ptr_vector<string> temp;
        temp.push_back(new string("hi"));
        temp.push_back(new string("hello"));
        return 0;
    }
    

    如果你只想要一个字符串容器,通常的做法是字符串向量:

    int main()
    {
        std::vector<string> temp;
        //s1 and s2 manage their own lifetimes
        //(and will be destructed at the end of the scope)
        string s1 = "hi";
        string s2 = "hello";
        //temp[0] and temp[1] refer to copies of s1 and s2.
        //The vector manages the lifetimes of these copies,
        //and will destroy them when it goes out of scope.
        temp.push_back(s1);
        temp.push_back(s2);
        return 0;
    }
    

    ptr_vector 旨在使具有值语义的多态对象更容易。如果你的字符串一开始就不是多态的,那么ptr_vector 是完全没有必要的。

    【讨论】:

    • 感谢详细解释!
    【解决方案2】:

    ptr_vector 旨在存储指向动态分配对象的指针。然后它取得它们的所有权并在其生命周期结束时将它们删除。如果将指针传递给无法删除的对象,则会得到未定义的行为。

    int main(void)
    {
        boost::ptr_vector<std::string> temp;
        temp.push_back(new std::string("hi"));
        temp.push_back(new std::string("hello"));
        return 0;
    }
    

    【讨论】:

    • 可能是它会自动清理,这可以解释它为什么会崩溃。
    • 不要写这段代码(一般情况下代码不完全包含在 main 中)。如果new std::string("hello")抛出,new std::string("hi")创建的字符串不会被删除,如果temp.push_back(s1)抛出,new std::string("hello")创建的字符串不会被删除。
    • @Mankarse 好点。我只是想说明堆损坏背后的问题。我更改了代码,但我不知道如果 new 表达式抛出,boost::ptr_vevtor::push_back 有什么保证。
    • @juanchopanza: push_back 立即获得提供的指针的所有权,如果push_back 操作抛出,将释放提供的指针。如果 new 抛出,push_back 将永远无法到达,因此无关紧要。
    【解决方案3】:

    如果您不打算将指针推回它,那么使用 ptr_vector 是没有意义的。

    要么使用 std::vector 要么推回一个用 new 关键字分配的字符串。

    【讨论】:

      猜你喜欢
      • 2011-05-07
      • 1970-01-01
      • 1970-01-01
      • 2017-07-06
      • 2016-06-24
      • 2014-12-17
      • 2011-06-08
      • 2011-06-01
      • 2011-09-09
      相关资源
      最近更新 更多