Boost logo

Boost Users :

From: roland kapl (roland.kapl_at_[hidden])
Date: 2021-01-06 11:49:07


Dear Boost-Experts!

I'm trying to use a ptr_map along with boost property trees. I need to store pointers to specific parts of a built up property tree to access these parts later on for easy insertion there.
However, when the ptr_map is cleared/destroyed, I get memory access violations/stack overflow messages for my test cases.

The ptr_map (typedef treeMap) is globally defined within a std::map to a ptr_map to property trees as follows (I know this isn't good practice, but passing it as a reference didn't make a difference, so I left it that way):
namespace pt = boost::property_tree;
typedef boost::ptr_map<std::string, pt::ptree> treeMap;
std::map<std::string, treeMap> parentTableTrees;

The property tree is defined as follows in this function (this builds a property tree from tabular data in the passed table variable "data" using definitions form table variable "control"):
std::string TreeizeRelD::writeTreeAndCreateXML(const std::vector<std::vector<std::string>>& control,
    const std::vector<std::vector<std::vector<std::string>>>& data, int *result)
{
    std::string resultString;

    pt::ptree &propTree = pt::ptree();
    std::string returnStr = TreeizeRelD::writeTree(control, data, propTree);
    *result = 0;
    if (returnStr != "") {
        *result = 1;
        return returnStr;
    }
    returnStr = TreeizeRelD::createXML(propTree, resultString);
    if (returnStr != "") {
        *result = 1;
        return returnStr;
    }
    // here the memory access violation occurs:
    parentTableTrees.clear();
    return resultString;
}

In function writeTree the propTree (being passed by ref as ptTree) is populated in following three lines:

std::string TreeizeRelD::writeTree(const std::vector<std::vector<std::string>> &control,
                   const std::vector<std::vector<std::vector<std::string>>> &data,
                   pt::ptree & ptTree)
...
                // FIRST LINE
                parentTableTrees[subRootNode].insert(keyPair.first, &ptTree.add_child(subRootNode, keyPair.second));
...
      // iterate through all parent key record collections referred to by subtables parentNode (rootnode + optional subnode)
      for (treeMap::value_type && parentKeysPair : parentTableTrees.find(lookupNode)->second) {
           // iterate through all records (ptrees) in key collection
           for (pt::ptree::iterator parentRecPair = parentKeysPair.second->begin(); parentRecPair != parentKeysPair.second->end(); ++parentRecPair) {
                pt::ptree &parentRecPtree = parentRecPair->second;
...
                // SECOND LINE
                // parentRecPair is an iterator variable from the ptr_map:
                parentTableTrees[subRootNode].insert(rowsFK, &parentRecPair->second.get_child(subnodeFRec));
...
                // THIRD LINE
                // parentRecPtree is the referenced property tree itself:
                parentTableTrees[subRootNode].insert(rowsFK, &parentRecPtree.put_child(subnodeOfParent, foreignRecordset));

I already have the suspicion that the memory access violation comes from ptr_map taking ownership of the pointers (references) passed to it in the above three lines and that these are all created on the stack and not the heap, where ptr_map expects them to be.
When the ptr_map is finally destroyed, it tries to access memory, that's impossible to access...

But I didn't manage to successfully create heap objects that also do NOT copy the property tree objects, which is important as I only need references to the property trees.

Any help is appreciated.

-regards,
Roland



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net