Pointer Type STL Map, How can I Iterate?

Started by
22 comments, last by smart_idiot 18 years ago

//Skin.h
	std::map<std::string, std::string>* skinData;

//Skin.cpp
Skin::Skin{
	skinData=NULL; 
}

void Skin::Read( std::string para_loadKey, std::map<std::string, std::string>& para_skinData ){
	skinData=&para_skinData; 
	Read( para_loadKey);
}

//The below is a segmentation Error
std::cout << (*skinData)["subject"];


Segmentation Error Descriptions: Program received signal SIGSEGV, Segmentation fault. 0x0804faee in std::_Rb_tree<std::string, std::pair<std::string const, std::string>, std::_Select1st<std::pair<std::string const, std::string> >, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > >::_M_begin (this=0x0) at stl_tree.h:462 462 { return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); } (gdb) bt #0 0x0804faee in std::_Rb_tree<std::string, std::pair<std::string const, std::string>, std::_Select1st<std::pair<std::string const, std::string> >, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > >::_M_begin (this=0x0) at stl_tree.h:462 #1 0x080505c5 in std::_Rb_tree<std::string, std::pair<std::string const, std::string>, std::_Select1st<std::pair<std::string const, std::string> >, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > >::lower_bound (this=0x0, __k=@0xbfbfe270) at stl_tree.h:1146 #2 0x08050665 in std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > >::lower_bound ( this=0x0, __x=@0xbfbfe270) at stl_map.h:540 #3 0x08051aed in std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > >::operator[] ( this=0x0, __k=@0xbfbfe270) at stl_map.h:336 #4 0x08063f4d in Skin::ParseFunctions (this=0xbfbfe3f0, para_skinTypeValue=@0xbfbfe2c0) at Skin.cpp:210 #5 0x08064833 in Skin::Read (this=0xbfbfe3f0, para_loadKey=@0xbfbfeb68) at Skin.cpp:175 #6 0x0804ee8a in main (argc=2, argv=0xbfbfec30) at new_shenu.cpp:139 Please,
Advertisement
	std::map<std::string,std::string>::pointer ploop;	for( ploop=skinData->begin(); ploop!=skinData->end(); ploop++ ){		std::cout << loop->first << "=" << loop->second << "\n";	}


I want to run this too.
compiles fine.
Segmentation Error.
What's going on?
You don't provide nearly enough information to know for sure, but it sounds to me as though you've got a map that hasn't been created yet. Or, given the form of your read function, it was created and then destroyed before you used your pointer.

CM
			mainConfig.SetConfig( "./system/db/" + mainParameter.GetParameterValue("db") + "/config.cgi" );			std::map<std::string, std::string> nextDbf;			algorithms::Instance().ParseData( nextDbf, "./system/db/" + mainParameter.GetParameterValue("db") + "/data.cgi" );			if ( mainConfig.GetConfigValue("SnPageLine") == "" )				mainConfig.SetConfig("SnPageLine","1");			int countData=0;			std::string tempifstream;			for( int i=(int)algorithms::Instance().ToInt( nextDbf["dbf"] )-1; i > 0; i-- ){				tempifstream="./system/db/" + mainParameter.GetParameterValue("db") + "/data/" + algorithms::Instance().ToString(i) + ".cgi";				if( ifstream( tempifstream.c_str() ) ){					mainData.SetData( algorithms::Instance().ToString(i), "./system/db/" + mainParameter.GetParameterValue("db") + "/data/" + algorithms::Instance().ToString(i) + ".cgi" );					countData++;				}				if ( countData == (int)algorithms::Instance().ToInt(mainConfig.GetConfigValue("SnPageLine")) )					break;			}			std::map< std::string, std::map< std::string, std::string > >::iterator mainlooparray[countData];			int countDataTrack=0;			for( std::map< std::string, std::map< std::string, std::string > >::iterator mainloop=mainData.GetData().begin(); mainloop != mainData.GetData().end(); ++mainloop ){					mainlooparray[countDataTrack]=mainloop;					countDataTrack++;			}			std::map< std::string, std::map< std::string, std::string > >::iterator mainloop;			std::map< std::string, std::string >::iterator mainloop2;			print::Instance().Header( "success4" );			Skin skin("system/skins/list.shenu", mainCookie, mainParameter, mainPath, mainConfig );			print::Instance().Body( "" );			skin.Read("Head");			for ( int i=0; i<countData; i++ ){				mainloop=mainlooparray;				for ( mainloop2=mainloop->second.begin(); mainloop2!=mainloop->second.end(); ++mainloop ){					std::cout << mainloop2->first << "=" << mainloop2->second;				}				//skin.Read("Body", mainloop->second );			}			skin.Read("Tail");			print::Instance().Tail( "" );

This is my main.

please help me.
It is kind of a follow up from this:
http://www.gamedev.net/community/forums/topic.asp?topic_id=385110
The first thing that comes to mind is this line:
for ( mainloop2=mainloop->second.begin(); mainloop2!=mainloop->second.end(); ++mainloop ){

I suspect you meant to increment mainloop2. That should have lead to an infinite loop, but you probably got [un]lucky in that once mainloop went out of bounds, it triggered mainloop2==mainloop->second.end() You then exit the loop, but mainloop is still out of bounds, so your read function fails.

CM
I really seriously can't find the syntax for incrementing mainloop2,
can you please tell me?
The syntax for incrementing mainloop2 would be ++mainloop2, i.e.:
for ( mainloop2=mainloop->second.begin();      mainloop2!=mainloop->second.end();      ++mainloop2 ){	std::cout << mainloop2->first << "=" << mainloop2->second;}

Question: What is the return type of the member function mainData.GetData()? If it returns by value then this loop:
for( std::map< std::string, std::map< std::string, std::string > >::iterator mainloop=mainData.GetData().begin(); mainloop != mainData.GetData().end(); ++mainloop ){	mainlooparray[countDataTrack]=mainloop;	countDataTrack++;}

will be comparing iterators into different copies of the same map, which is undefined behaviour. It's a bit like if you did:
std::map< std::string, std::map< std::string, std::string > > temp1 = mainData.GetData();std::map< std::string, std::map< std::string, std::string > > temp2 = mainData.GetData();for (std::map< std::string, std::map< std::string, std::string > >::iterator mainloop=temp1.begin(); mainloop != temp2.end(); ++mainloop){	mainlooparray[countDataTrack]=mainloop;	countDataTrack++;}

If mainData.GetData() returns by reference then you're OK (on that point).

Σnigma
Quote:Original post by Tradone
I really seriously can't find the syntax for incrementing mainloop2,
can you please tell me?

It works just like incrementing mainloop: ++mainloop2.

CM
std::map< std::string, std::map< std::string, std::string > > GetData(){
return data;
};


it returns std::map< std::string, std::map< std::string, std::string > >

This topic is closed to new replies.

Advertisement