Nested STL maps?
-
Currently writing a memory management system and I decided it'd be the logical thing to use stl maps to store various data. I'm very new to stl so I don't really understand the ins and outs of it yet, so I'm stuck on a problem which *should* be easy, but I'm doing something wrong. I'm basically keeping a map of maps, with a unique string as the key to each of the maps. Here's one of my insert functions: bool CHeapStore::_insert (heapHeader_t *header) { map tmpMap; pair< map >::iterator, bool> p; tmpMap.insert(pair(header->id, header)); p = s_heaps.insert(pair >(header->name, tmpMap)); s_mmStashing = false; return p.second == true ? true : false; } The program crashes on the s_heaps.insert() and returns the debugger to this in xtree: _Pairib insert(const value_type& _Val) { // try to insert node with value _Val _Nodeptr _Trynode = _Root(); // crashes here What am I doing wrong? I've also tried other insertion methods, but this is the most direct one. The s_heap is an empty map when it crashes, it's the first call to the insert function. Thank you so much for any help. btw, i'm using the default stl library that comes with MSVC .NET 2003. -j
-
Currently writing a memory management system and I decided it'd be the logical thing to use stl maps to store various data. I'm very new to stl so I don't really understand the ins and outs of it yet, so I'm stuck on a problem which *should* be easy, but I'm doing something wrong. I'm basically keeping a map of maps, with a unique string as the key to each of the maps. Here's one of my insert functions: bool CHeapStore::_insert (heapHeader_t *header) { map tmpMap; pair< map >::iterator, bool> p; tmpMap.insert(pair(header->id, header)); p = s_heaps.insert(pair >(header->name, tmpMap)); s_mmStashing = false; return p.second == true ? true : false; } The program crashes on the s_heaps.insert() and returns the debugger to this in xtree: _Pairib insert(const value_type& _Val) { // try to insert node with value _Val _Nodeptr _Trynode = _Root(); // crashes here What am I doing wrong? I've also tried other insertion methods, but this is the most direct one. The s_heap is an empty map when it crashes, it's the first call to the insert function. Thank you so much for any help. btw, i'm using the default stl library that comes with MSVC .NET 2003. -j
If you are using a map of maps and don't care about existence before inserting (you are willing to overwrite values if the keys match) then try the following: declaration: map < string , map < int , heapHeader_t* > > storage. To insert, just use the subscripts for access. If the items does not exist in the map, the map will automatically insert the item using the keys from the subscripts. storage[string][int] = headHeader_t* item; But removing items from the map is different question. Hopefully this is helpful. Glenn
-
Currently writing a memory management system and I decided it'd be the logical thing to use stl maps to store various data. I'm very new to stl so I don't really understand the ins and outs of it yet, so I'm stuck on a problem which *should* be easy, but I'm doing something wrong. I'm basically keeping a map of maps, with a unique string as the key to each of the maps. Here's one of my insert functions: bool CHeapStore::_insert (heapHeader_t *header) { map tmpMap; pair< map >::iterator, bool> p; tmpMap.insert(pair(header->id, header)); p = s_heaps.insert(pair >(header->name, tmpMap)); s_mmStashing = false; return p.second == true ? true : false; } The program crashes on the s_heaps.insert() and returns the debugger to this in xtree: _Pairib insert(const value_type& _Val) { // try to insert node with value _Val _Nodeptr _Trynode = _Root(); // crashes here What am I doing wrong? I've also tried other insertion methods, but this is the most direct one. The s_heap is an empty map when it crashes, it's the first call to the insert function. Thank you so much for any help. btw, i'm using the default stl library that comes with MSVC .NET 2003. -j
I converted your code into a small test program,
#include <map>
#include <string>struct heapHeader
{
std::string name_ ;
int id_ ;
void * p_ ;
} ;struct heap
{
std::map<std::string, std::map<int, heapHeader *> > s_heaps ;bool insert ( heapHeader \*header) { std::map<int, heapHeader \*> tmpMap; std::pair< std::map<std::string, std::map<int, heapHeader \*> >::iterator, bool> p; tmpMap.insert(std::pair<int, heapHeader \*>(header->id\_, header)); p = s\_heaps.insert(std::pair<std::string, std::map<int, heapHeader \*> >(header->name\_, tmpMap)); return p.second ; }
} ;
int main( )
{
heap h ;
heapHeader * ph = new heapHeader ;
ph->id_ = 0 ;h.insert ( ph ) ; return 0;
}
and it compiles and runs as expected. So I don't know what your problem is. However I think your code is wrong. In the first place I wouldn't use a map where the key is embedded in the type, a set would be more efficient, you can create specific predicates to allow the object to be sorted according to its id or name. Secondly what if you insert a subsequent heapHeader with the same name? I assume this is legal? This way your maps of id-heapheader would have more than one member. Anyway I would consider rewriting 'insert' along these lines,
void insert ( heapHeader \*header)
{
std::pair< std::mapname_, std::map<int, heapHeader *> ()));
(*p.first).second.insert ( std::make_pair ( header->id_, header )) ;
}Although perhaps the syntax could be tidied. The point is that std::map::insert never fails (other than through memory exhaution, in which case it throws an exception), it either inserts a new entry and returns 'true' in the second part of the pair, or returns false. In either case the first part of the return is an iterator to the appropriate entry. Hope that made some sense. Paul