Click to See Complete Forum and Search --> : STL Container with Struct contents -- Help!


quantass
January 13th, 2003, 02:50 PM
I'm having troubles using the STL containers, MAP and DEQUE. I'm trying to create a MAP container that contains another MAP container that contains a DEQUE container. Each container uses a struct for its contents. My problem lies in actually using the struct contents of any one of these containers. My code follows.
------------------
#include <map>
#include <deque>

typedef struct DequeLHStruct
{
char Options;
} DequeLayerHistoryStruct;

typedef std::deque<DequeLHStruct> DequeLHType;

typedef struct MapLStruct
{
string strActionName;
DequeLHType LH;
} MapLayerStruct;

typedef std::map<long,MapLStruct> MapLType;

typedef struct MapDocStruct
{
string strActionSetName;
MapLType Layer;
} MapDocStruct;

typedef std::map<long,MapDocStruct> MapDocType;

int main(int argc, char* argv[])
{
DWORD error;

long docID, layerID;

MapDocType LHRepository;
MapDocStruct myDocStruct;
MapDocType::const_iterator myDocIter;

MapLType myLayer,layerItem;
MapLStruct myLayerStruct, *layerStruct;
MapLType::const_iterator myLayerIter;

DequeLHStruct myLHStruct;

docID=144;
layerID=2;

myDocStruct.strActionSetName="Document 144";
LHRepository.insert(MapDocType::value_type(docID,myDocStruct));

myLayerStruct.strActionName="Layer Name: #2";
LHRepository[docID].Layer.insert(MapLType::value_type(layerID,myLayerStruct));

myLHStruct.Options=33;
LHRepository[docID].Layer[layerID].LH.push_back(myLHStruct);

if (LHRepository[docID].Layer.size()==0)
{error=0; goto cleanup;}

for (myLayerIter=LHRepository[docID].Layer.begin(); myLayerIter!=LHRepository[docID].Layer.end(); myLayerIter++)
{
cout << "Index: " << myLayerIter->first << endl;

layerStruct=(MapLStruct *)&(*myLayerIter);

cout << "Name: "<< layerStruct->strActionName << endl; // <------------ This line CRASHES!
}

cleanup:

return 0;
}

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

The problem occurs within the FOR statement when i try to access the contents of the "myLayerIter" iterator. From my understanding the dereferenced iterator should give me the contents (a struct) for the particular layer its pointing to. What i do is get the address of this contents and cast it into a MapLStruct pointer so that i may access the contents properly. When i go to display a member of this struct the app crashes. When I do a "layerStruct->LH.size()" the return value = 2, an incorrect #.

What's going on? How exactly do i access the struct contents from the iterator?

Paul McKenzie
January 13th, 2003, 04:48 PM
Here is your code, cleaned up for errors:

#include <windows.h>
#include <map>
#include <deque>
#include <iostream>

struct DequeLHStruct
{
char Options;
};

typedef std::deque<DequeLHStruct> DequeLHType;

struct MapLStruct
{
std::string strActionName;
DequeLHType LH;
};

typedef std::map<long,MapLStruct> MapLType;

struct MapDocStruct
{
std::string strActionSetName;
MapLType Layer;
};

typedef std::map<long,MapDocStruct> MapDocType;

using namespace std;

int main(int argc, char* argv[])
{
DWORD error;

long docID, layerID;

MapDocType LHRepository;
MapDocStruct myDocStruct;
MapDocType::const_iterator myDocIter;

MapLType myLayer,layerItem;
MapLStruct myLayerStruct;
MapLStruct *layerStruct;
MapLType::const_iterator myLayerIter;

DequeLHStruct myLHStruct;

docID=144;
layerID=2;

myDocStruct.strActionSetName="Document 144";
LHRepository. insert(MapDocType::value_type(docID,myDocStruct));


myLayerStruct.strActionName="Layer Name: #2";
LHRepository[docID].Layer. insert(MapLType::value_type(layerID,myLayerStruct)
);

myLHStruct.Options=33;
LHRepository[docID].Layer[layerID].LH.push_back(myLHStruct);

if (LHRepository[docID].Layer.size()==0)
{error=0; goto cleanup;}

for (myLayerIter=LHRepository[docID].Layer.begin(); myLayerIter!=LHRepository[docID].Layer.end(); myLayerIter++)
{
cout << "Index: " << myLayerIter->first << endl;
layerStruct = const_cast<MapLStruct*>(&myLayerIter->second);
cout << "Name: " << layerStruct->strActionName << endl;
}

cleanup:

return 0;
}

Note that you may have to specify "layerStruct->strActionName.c_str()" in your cout statement if you are using the VC++ compiler. For some reason, my version believes that there is no operator << for std::string.

myLayerIter is a map iterator. Map iterators always point to pairs, not your actual data items. To get to your data, you either specify "first" or "second", depending on whether you want the key or the data, respectively.

Anothter thing: get rid of the typedef's for your structs. The "typedef" is superfluous and no longer necessary in a C++ program (unless your structs are in a header file, and the header file can be used in both C and C++ modules).

Regards,

Paul McKenzie