Dear All!

 

After finding some inspiration on https://stackoverflow.com/questions/4088387/how-to-store-pointers-in-map , I’ve succeeded storing the property tree pointers in a std::map…

 

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)

{

    // now the map is local…

   typedef std::map<std::string, pt::ptree*> treeMap;

    std::map<std::string, treeMap> parentTableTrees;

 

 

….

        std::string subRootNode = parentNode + (subnodeOfParent != "" ? "." + subnodeOfParent : "");

        std::string tableLookup = subRootNode + "." + rootElemRec;

        // simply add records if no foreign key name exists (usually the top (root) table)

        if (foreignKeyName == "") {

            for (std::pair<std::string, pt::ptree> && keyPair : tables[tableLookup]) {

                parentTableTrees[subRootNode].insert(std::make_pair(keyPair.first, &ptTree.add_child(subRootNode, keyPair.second)));

                // iterate through all parent key record collections referred to by subtables parentNode (rootnode + optional subnode)

                for (std::pair<std::string, pt::ptree*> && 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) {

                        // important here: assign a reference to parentRecPtree (pointer!), otherwise a copy is created!

                        pt::ptree &parentRecPtree = parentRecPair->second;

                                    parentTableTrees[subRootNode].insert(std::make_pair(rowsFK, &parentRecPair->second.get_child(subnodeFRec)));

…                 

                                parentTableTrees[subRootNode].insert(std::make_pair(rowsFK, &parentRecPtree.put_child(subnodeOfParent, foreignRecordset)));

 

 

 

The complete source of this: https://github.com/rkapl123/OreControl/blob/master/OreMgr/TreeizeRelD/treeizereld.cpp

 

 

-regards,

Roland

 

 

----------------------------------------------------------------------

 

Message: 1

Date: Wed, 6 Jan 2021 11:49:07 +0000

From: roland kapl <roland.kapl@hotmail.com>

To: "boost-users@lists.boost.org" <boost-users@lists.boost.org>

Subject: [Boost-users] boost ptr_map memory access violation

                (stack/heap problem)

Message-ID:

                <AM0PR03MB424285F7832EDC3C73C96860EDD00@AM0PR03MB4242.eurprd03.prod.outlook.com>

               

Content-Type: text/plain; charset="us-ascii"

 

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

 

-------------- next part --------------

HTML attachment scrubbed and removed

 

------------------------------

 

Subject: Digest Footer

 

_______________________________________________

Boost-users mailing list

Boost-users@lists.boost.org

https://lists.boost.org/mailman/listinfo.cgi/boost-users

 

 

------------------------------

 

End of Boost-users Digest, Vol 5444, Issue 1

********************************************