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
https://lists.boost.org/mailman/listinfo.cgi/boost-users
------------------------------
End of Boost-users Digest, Vol 5444, Issue 1
********************************************