Reputation: 938
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(¤tModelElement);
// 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 worksdf::
is the namespace of the lib I neednddlgen::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.
Upvotes: 0
Views: 304
Reputation: 392999
Boost Pointer Containers explicitly own their elements. Consequently there cannot be shared ownership.
Just store
shared_ptr<T>
) in the container (if the container should keep the elements alive)weak_pointer<T>
) in the container (if the container should be able to detect stale elements)T*
) if you know that elements will always live longer than the container.Upvotes: 1
Reputation: 3260
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 ¤tModelElement
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.
Upvotes: 1