简体   繁体   中英

Boost shared_ptr in ptr_list

I am new to C++ and quickly began using the boost library, since it offers a lot of functionality I need. Especially the BOOST_FOREACH is very useful to me so I can easily iterate through a boost ptr_list . Eventually I needed to use another library, which uses boosts shared_ptr .

Here is my code:

bool SdfParser::parseDataStructure(sdf::ElementPtr sdfRoot)
{
    /* sdfRoot is the root of a xml-like data structure. The first child is "world" and the childs of "world" are several "model" elements */

    nddlgen::models::Workspace* workspace = new nddlgen::models::Workspace();
    workspace->setName("workspace");

    this->_armModel->setWorkspace(workspace);

    sdf::ElementPtr workspaceElement = sdfRoot->GetElement("world");
    sdf::ElementPtr currentModelElement = workspaceElement->GetElement("model");

    nddlgen::types::ModelList models;

    // The sdf lib only offers a useless data structure for the models, so it is
    // converted into a ModelList here
    while (currentModelElement != nullptr)
    {
        models.push_back(&currentModelElement);

        // Iterate
        currentModelElement = currentModelElement->GetNextElement("model");
    }

    if (!this->instantiateModels(models))
    {
        return false;
    }

    if (!this->calculateDependencies(models))
    {
        return false;
    }

    return true;
}

Explanation:

  • nddlgen:: is the namespace of my work
  • sdf:: is the namespace of the lib I need
  • nddlgen::types::ModelList is a typedef from boost::ptr_list<sdf::ElementPtr>
  • sdf::ElementPtr is a typedef from boost::shared_ptr<sdf::Element>

Problem:

The code shown here compiles without errors or warnings, but I get the following output when I run the compiled program: *** Error in './nddl-generator-cli': double free or corruption (out): 0x00007ffd0ff46460 *** .

What I tried:

I tried to retrieve the sdf::Element from sdf:ElementPtr and changed the other code accordingly, but it would not work. I would get some compiler errors. Anyway, I would not like to ignore the libraries suggested use of sdf::ElementPtr .

Later I tried to remove the & in the argument of the push_back function, but this does not compile, of course, since the push_back function requires a pointer.

Also I dont wan't to go without boost's BOOST_FOREACH , so I also don't want to use any other type of list.

How can it be that boosts ptr_list does not work with boosts shared_ptr ? What can I do to use sdf::ElementPtr as well as BOOST_FOREACH ?

[Edit] Solution:

See accepted answers, especially comments. The trick was to use std::list instead of boosts ptr_list , since BOOST_FOREACH also accepts those.

It's very strange that you already use shared_ptr for currentModelElement , and but put the address of that shared_ptr in ptr_list. You should put shared_ptr in a normal list .

And when you put &currentModelElement in ptr_list , all the element in ptr_list are actually the same. They all point to the address of a local variable which is a shared_ptr , when ptr_list' destructor is called, the same shared_ptr pointer is deleted several times.

Boost Pointer Containers explicitly own their elements. Consequently there cannot be shared ownership.

Just store

  • shared pointers ( shared_ptr<T> ) in the container (if the container should keep the elements alive)
  • weak pointers ( weak_pointer<T> ) in the container (if the container should be able to detect stale elements)
  • raw pointers ( T* ) if you know that elements will always live longer than the container.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM