views:

561

answers:

2

I'm hacking together an editor for a game I'm working on and as part of that editor, I need to have textures, obviously. I've created a std::map variable as so,

std::map<std::string, unsigned int> textures;

In my image loading code, I have the following snippet.

unsigned int id;
glGenTextures(1, &id);
glBindTexture(GL_TEXTURE_2D, id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, imageWidth, imageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, imageData);
glBindTexture(GL_TEXTURE_2D, 0);

textures[filename] = id;

Now for some reason, I get a runtime error after attempting to use the above code. An access violation error, that, when debugged, points me to the std::map code itself, specifically, this portion:

_Nodeptr _Lbound(const key_type& _Keyval) const
 { // find leftmost node not less than _Keyval
 _Nodeptr _Pnode = _Root(); // ** this is the highlighted line **
 _Nodeptr _Wherenode = _Myhead; // end() if search fails

 while (!_Isnil(_Pnode))
  if (_DEBUG_LT_PRED(this->comp, _Key(_Pnode), _Keyval))
   _Pnode = _Right(_Pnode); // descend right subtree
  else
   { // _Pnode not less than _Keyval, remember it
   _Wherenode = _Pnode;
   _Pnode = _Left(_Pnode); // descend left subtree
   }

 return (_Wherenode); // return best remembered candidate
 }

I'm only making one call to my image loading function just to test the system. I checked the variables and both the filename and id variables are correct. Any ideas as far as to what could be causing the runtime crash?

+1  A: 

It seems like the map hasn't been constructed properly. The order of initialization is probably wrong. Is the map a static or global variable? Is your code part of a static object?

Mark Ransom
The map is a global object and the function is also global.
Doesn't matter if the function is global or not, it matters who's calling it. Is it being called from a global object's constructor?
Mark Ransom
A: 

Whenever I see code that uses a map like this:

   textures[filename] = id;

I go "oh-oh". This is because it is not clear what the code does it might:

  • create a new empty entry indexed by filename and replace its value with id
  • replace an existing value with id

To avoid not knowing what is going on, I have a very simple rule - I never use operator[] for maps.

anon
I try to avoid the [] entirely for all stl containers. It's laziness that drives people to use this which, like you say here doesn't have a definite result.
Brian
I avoid this too, but a lack of code clarity isn't going to cause a crash.
Tyler McHenry
As I said I was simply hacking it together and there are no other entries in there at this point. I just wanted to get a quick and dirty example running, before I moved on. I was actually just reading the debate on insert() vs the [] operator.
@Brian I think totally avoiding [] for vector might be going too far, though I have lately taken to using at() for all but the most obviously performance sensitive code, and have thus uncovered several embarassing little problems!
anon
@Steve It my be worthwhile re-writing your code to use insert() (pretty easy) and see if the point it fails at makes any more sense
anon
This does not answer the OP's question
Dave Hillier