开发者

stl::map issues

This must be me doing something stupid, but has anyone seen this behaviour before:

I have a map in a class member defined like so:

std::map <const std::string, int> m_fCurveMap;

all behaves fine in debug but all goes wrong in release mode. map gets initialised to some crazy number: m开发者_Python百科_fCurveMap [14757395258967641292]()

Any member I have after the map gets completely corrupted, ie if I put an int on the line after the map like this:

std::map <const std::string, int> m_fCurveMap;
int m_myIntThing;

and in my constructors set m_myIntThing to 0, after the constructor has been called m_myIntThing is some crazy number. If I move m_myIntThing to the line above the map everything for m_myIntThing is fine. This ends up causing big problems for me further down the line. Do I need to do something to the map in my constructor? I'm not at the moment.

I am using visual studio, this works fine with gcc. I only see the problem in release. The project is a dll.

If you have seen this kind of madness before please help its driving me mad. :-)

Many thanks, Mark


This has happened to me lots of times. Although it's hard to say in your case, a very likely reason is that you have different versions of the C run time library in between different projects. Check your "code generation" tab in the compiler settings for your different projects and make certain they are the same.

What's effectively happening is that different versions of the C run time libraries implement STL containers in different ways. Then when the different projects try to talk to each other, the meaning of what an std::map is (for instance) have changed and are no longer binary compatible.

The strange behavior is very likely some kind of heap corruption, or if it's being passed as a parameter to a function, stack corruption.


The problem is memory corruption of some kind.

A bug that I have seen often in C++ projects is using an object after it has been deleted.

Another possibility is a buffer overflow. It could be any object on the same stack or nearby on the heap.

A pretty good way to catch the culprit is to set a debugger breakpoint that fires on memory change. While the object is still good, set your breakpoint. Then wait until some code writes into that memory location. That should reveal your bug.


If you're getting your information from the VS debugger, I wouldn't trust what it is telling you for a Release DLL. The debugger can only be really trusted with Debug DLLs.

If program output is telling you this, then that's different -- in that case, you're not providing enough information.


Are you mixing a release DLL with a debug app?

Otherwise it sounds like memory corruption, although I can't say for sure.

  • Something else is stomping on memory
  • You're accessing deleted memory
  • You're returning a temporary by pointer or reference
  • etc

Any of these could appear to work fine in some cases as they're undefined behavior, and only in release mode do they blow up.


I had the exact same problem on g++, I got it resolved by removing the pragmas in a pragma paragraph before that. Eventhough the code is correct, I wonder if this is a compiler bug on the platform showing up when using stl::map in some situations.

#pragma pack(push,1)
xxxx
#pragma(pop)


Just to give a concrete example for the memory corruption:

typedef std::map<int, int> mymap_t;

static mymap_t static_init() { return mymap_t(); }

class foo {
   foo(): mymap(static_init()) {}

   //!> d'oh, don't reference!
   const mymap_t &mymap;
};

Accidentally, I defined a ref to a member variable and not the member variable itself. It gets initialized alright, but as soon as the scope of static_init() is left, the map is destroyed and the ref will just show up in debug as "std::map with 140737305218461 elements" (pretty-printed) or similar as it points to now unallocated meory (or worse).

Beware of accidental references!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜