Hi There,
I am using the Boost.MultiIndex and I am facing a problem that I am try
to resolving (debbuging) already about 20 hours...
I think I get the problem isolated, but I don't know how to solve,
and I don't know if this it is implemented.
So I decided to make a example, it is a little big, but I put it as resumed as I could and post here in order to know if anyone could help me out.
I will try to explain briefly here, I will copy the main() code right under the explanation, but the whole code of the example is in the end of the e-mail (with the classes and functions) If you want you could try to run too see what is the problem that I am talking about.)
When I try to access an pair of iterators pair
that I stored inside a class (propertystream_h),
somehow is changing to where the iterator points, I think it could
be because the object which has originate (Graph) the index is created, stored in in a static index (which I call _graphRep) from the DynamicGraphs, passed to a handler (Graph_h), and then after the Graph goes out of scope it is destroyed. When the Graph_h._localGraph (copy of the iterator->Graph returned by the insertion in the _graphRep) access its member _globalProperties (which is an index containing the fields:
{string _key, string _value, propertystream_h _props} from the struct
globalPropSchema) through a iterator (let's call it: gpit), then it is fine. But then when I try to access through the gpit->_props._propRangeIt.first, the iterator of the propertystream_h (_propRangeIt.first), then the iterators, some how are messed up. ( -> in this example it points to last element, and then when I get next, never finds the end(). (sometimes it return some trash, sometimes I get segmentation fault).
So I would like to know why it is messing with the iterator? And how could I solve this problem?
that's it,
best regards,
Rodrigo
P.S.: I hope someone can help me...
copy of the main():
int main(){
DynamicGraphs dg;
Graph_h graph_h;
propertystream_h propS;
property_h prop_h;
GlobalPropIterator gpit;
GlobalProp_h gp_h;
propertystream_h ps_h;
property_h p_h;
graph_h = dg.createGraph("COI:0351-123-4555");
if (!graph_h)
cout << "Unsuccessful creation!"<lookupLocalProp("name");
while(!ps_h.end()){
cout << "LocalProperties: ";
p_h=ps_h.next();
cout << "Key: " << p_h.key() << " Value: " << p_h.value() < after a lot of debugging (about 16h) OI found out that
// it seems that during the creation of a graph,
// when it passes the graph to graph_h, and goes out of scope, it keep the
// iterator reference to the first element, but just that... the next
// gives me segmentation fault. Anyone knows how to pass the graph and the its members
// the indexes-repositories as value, so it would not depend on the pointing to
// the graph that was freed from the memory?
gpit = graph_h->properties("*");
if (!gpit)
cout << "Not found any property in the globalProperties Repository."<
#include
#include
#include
#include
#include
#include
#include
#include <climits>
#include <iomanip>
#include <iostream>
#include <ctime>
#include <string>
#if !defined(NDEBUG)
#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
#endif
using std::string;
using std::pair;
using std::ostream;
using std::cout;
using std::endl;
using boost::multi_index_container;
using namespace boost::multi_index;
struct property {
string _key;
string _value;
/// Default Constructor
property(){}
/// Constructor with parameters: initialize the name and graph
property(string key, string value) : _key(key), _value(value) {}
/// Copy Contructor
property(const property &pm) : _key(pm._key), _value(pm._value) {}
//For debugging TODO: delete later
friend ostream& operator<<(ostream& os, const property &p){
os << "Key: " << p._key << " value: " << p._value << endl;
return os;
}
};
/// Indexing in the data structure PropMap
typedef multi_index_container<
property,
indexed_by<
hashed_non_unique<
BOOST_MULTI_INDEX_MEMBER(property, string, _key)
>
>
propIndex;
typedef propIndex::iterator propIt;
class property_h {
private:
/// Access to properties through the iterator
propIt _pit;
public:
/// Default Constructor
property_h(){}
/// Constructor with Parameters: for lookup of Nodes
property_h (const propIt &it) : _pit(it){}
/// Constructor with Parameters: for lookup of Nodes
property_h (const property_h &h) : _pit(h._pit){}
/// Returns the key from the property being handled
string key() const {return _pit->_key;}
/// Returns the value from the property being handled
string value() const {return _pit->_value;}
};
class propertystream_h {
/// _propRangeIt: for keeping a range in order to iterate over the graphs
pair _propRangeIt;
/// _noMatches: true if there are no matches during the lookup function
bool _noMatches;
public:
/// Default Constructor
propertystream_h() : _noMatches(true){}
/// Constructor with parameters for local lookup
propertystream_h(pair rangeIt, bool noMatches) :
_propRangeIt(rangeIt), _noMatches(noMatches){ }
/// Default Constructor
propertystream_h(const propertystream_h &ps) :
_propRangeIt(ps._propRangeIt), _noMatches(ps._noMatches){}
// returns null_h on end of stream ...
property_h next(){
return property_h(_propRangeIt.first++);
}
/// This function returns true whenever is the end of the stream
bool end(){
return (_propRangeIt.first == _propRangeIt.second);
}
/// Overload operator!: shows if a creation was unsuccessful
bool operator!(){ return _noMatches; }
};
struct globalPropSchema{
string _key;
string _value;
propertystream_h _props;
/// Default Constructor
globalPropSchema() : _key(""), _value(""), _props(){}
/// Parameter Constructor
globalPropSchema(string k, string value, propertystream_h props) : _key(k),
_value(value), _props(props){}
/// Copy Constructor
globalPropSchema(const globalPropSchema &gps) : _key(gps._key), _value(gps._value),
_props(gps._props){}
//TODO: Delete it: Debug
friend ostream& operator<<(ostream &os, const globalPropSchema &gps){
os << "Key: " << gps._key << " Value: "<< gps._value << " PropertyStreamAdress: "
<< &gps._props <,
composite_key_compare<
std::greater<string>,
std::less<string>
>
>
>
grobalProperties;
/// Iterator for the data structure of the global properties index
typedef grobalProperties::iterator globalPropIt;
class GlobalProp_h{
private:
/// Access to globalPropertiest items through the iterator
globalPropIt _gpit;
public:
/// Default Constructor
GlobalProp_h(){}
/// Constructor with Parameters: for lookup of Nodes
GlobalProp_h (const globalPropIt &it) : _gpit(it){}
/// Copy Constructor
GlobalProp_h (const GlobalProp_h &gph) : _gpit(gph._gpit){}
/// Access to key of globalPropeties items
string key(){ return _gpit->_key;}
/// Access to value of globalPropeties items
string value(){return _gpit->_value;}
propertystream_h propertyStreamHandler(){
return _gpit->_props;
}
};
/// Iterator for the data structure of the global properties index
typedef grobalProperties::iterator globalPropIt;
class GlobalPropIterator{
private:
/// _propRangeIt: for keeping a range in order to iterate over the graphs
pair _globalPropRangeIt;
/// _noMatches: true if there are no matches during the lookup function
bool _noMatches;
public:
/// Default Constructor
GlobalPropIterator(){}
/// Constructor with parameters for local lookup
GlobalPropIterator(pair rangeIt, bool noMatches) :
_globalPropRangeIt(rangeIt), _noMatches(noMatches){}
/// Default Constructor
GlobalPropIterator(const GlobalPropIterator &gpi) :
_globalPropRangeIt(gpi._globalPropRangeIt), _noMatches(gpi._noMatches){}
// returns null_h on end of stream ...
GlobalProp_h next(){
return GlobalProp_h(_globalPropRangeIt.first++);
}
/// This function returns true whenever is the end of the stream
bool end(){
return (_globalPropRangeIt.first == _globalPropRangeIt.second);
}
/// Overload operator!: shows if a creation was unsuccessful
bool operator!(){ return _noMatches; }
};
class Graph {
private:
propIndex _localPropRep;
/// Repository for the properties of the global properties related to the graph;
grobalProperties _globalPropRep;
public:
// TODO: Really constructors
/// Default Constructor
Graph() {}
/// Copy constructors
Graph(const Graph &g) : _localPropRep(g._localPropRep),
_globalPropRep(g._globalPropRep){}
bool addProperty(string key, string value);
GlobalPropIterator properties(string pattern) const;
/// Function to lookup Local Properties
propertystream_h lookupLocalProp(string pattern);
friend class Graph_h;
};
/// GraphMap: Data Structure for setting an index in the uniqueGraphName and retrieving handler Graph_h
struct graphMap {
string _name;
Graph _graph;
/// Default Constructor
graphMap(){}
/// Constructor with parameters: initialize the name and graph
graphMap(string uniqueGraphName, Graph graph) :
_name(uniqueGraphName), _graph (graph) {}
/// Constructor with parameters: initialize the name and graph
graphMap(const graphMap &gm) : _name(gm._name), _graph (gm._graph) {}
};
///ordered_unique Index in the data structure graph_hm
typedef multi_index_container<
graphMap,
indexed_by<
ordered_unique<
BOOST_MULTI_INDEX_MEMBER(graphMap,string,_name)
>
>
graphIndex;
/// Defing an iterator for the graphMapIndex
typedef graphIndex::iterator graphIt;
class Graph_h {
private:
/// \brief GraphIterator: Iterator pointing to the Graph
graphIt _git;
Graph _localGraph;
bool _createSuccess;
public:
/// Default Constructor
Graph_h() : _createSuccess(false) {}
/// Constructor with Parameters: for creation of Graphs
Graph_h ( pair creation) :
_git(creation.first), _createSuccess(creation.second){
_localGraph = creation.first->_graph;
}
/// Constructor with Parameters: for lookup of Graphs
Graph_h (const graphIt &it) :
_git(it), _createSuccess(false){
_localGraph = it->_graph;
}
/// Constructor with Parameters: for lookup of Graphs
Graph_h (const Graph_h &h) :
_git(h._git), _localGraph(h._localGraph), _createSuccess(h._createSuccess){}
bool operator!(){
return !_createSuccess;
}
/// Operator-> overloading: allows access to graph members
Graph* operator->() {return &_localGraph;}
};
propertystream_h Graph::lookupLocalProp(string pattern){
pair rangeIt;
propIt rangeItfirst = _localPropRep.find(pattern);
rangeIt.first = rangeItfirst;
rangeIt.second = _localPropRep.end();
if (rangeIt.first != _localPropRep.end())
// second parameter means that the variable noMatches, so false in case that found the key
return propertystream_h(rangeIt, false);
else
//No matches
return propertystream_h(rangeIt, true);
}
GlobalPropIterator Graph::properties(string pattern) const{
pair globalRangePropIt;
bool noMatchesTmp=false;
//Whole range
if (!pattern.compare("*")){
globalRangePropIt.first = _globalPropRep.begin();
globalRangePropIt.second = _globalPropRep.end();
}
if (globalRangePropIt.first == globalRangePropIt.second)
noMatchesTmp = true;
return GlobalPropIterator(globalRangePropIt, noMatchesTmp);
}
bool Graph::addProperty(string key, string value){
bool boolLocal, boolGlobal;
pair rangePropIt;
string globalKey = "graph:";
globalKey.append(key); // "graph:namePorperty"
boolLocal = _localPropRep.insert(property(key,value)).second;
//Defining the whole range for iterate over the local properties
rangePropIt.first = _localPropRep.begin();
rangePropIt.second = _localPropRep.end();
//Debug
propIt it = rangePropIt.first;
cout << "How it should be showed when accessing the iterator..."<lookupLocalProp("name");
while(!ps_h.end()){
cout << "LocalProperties: ";
p_h=ps_h.next();
cout << "Key: " << p_h.key() << " Value: " << p_h.value() < after a lot of debugging (about 16h) OI found out that
// it seems that during the creation of a graph,
// when it passes the graph to graph_h, and goes out of scope, it keep the
// iterator reference to the first element, but just that... the next
// gives me segmentation fault. Anyone knows how to pass the graph and the its members
// the indexes-repositories as value, so it would not depend on the pointing to
// the graph that was freed from the memory?
gpit = graph_h->properties("*");
if (!gpit)
cout << "Not found any property in the globalProperties Repository."<http://dsl.gmx.de/?ac=OM.AD.PD003K11308T4569a