stl::地图问题
这一定是我做了一些愚蠢的事情,但是以前有人见过这种行为吗:
我在类成员中有一个映射,如下定义:
std::map <const std::string, int> m_fCurveMap;
在调试中一切都表现良好,但在发布模式下一切都出错了。地图被初始化为一些疯狂的数字: m_fCurveMap [14757395258967641292]()
地图完全损坏后我拥有的任何成员,即如果我在地图后面的行上放置一个 int ,如下所示
std::map <const std::string, int> m_fCurveMap;
int m_myIntThing;
:构造函数将 m_myIntThing 设置为 0,调用构造函数后 m_myIntThing 是一个疯狂的数字。如果我将 m_myIntThing 移动到地图上方的行,则 m_myIntThing 的一切都很好。这最终给我带来了大问题。我需要在构造函数中对地图做一些事情吗?我现在不在。
我正在使用 Visual Studio,这与 gcc 配合得很好。我只在发布时看到问题。该项目是一个dll。
如果你以前见过这种疯狂的行为,请帮助它让我发疯。 :-)
非常感谢, 标记
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_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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这种情况在我身上发生过很多次。尽管在您的情况下很难说,但很可能的原因是您在不同的项目之间有不同版本的 C 运行时库。检查不同项目的编译器设置中的“代码生成”选项卡,并确保它们是相同的。
实际上发生的情况是,不同版本的 C 运行时库以不同的方式实现 STL 容器。然后,当不同的项目尝试相互通信时,std::map 的含义(例如)已经改变,并且不再是二进制兼容的。
这种奇怪的行为很可能是某种堆损坏,或者如果它作为参数传递给函数,则可能是堆栈损坏。
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.
问题是某种内存损坏。
我在 C++ 项目中经常看到的一个错误是在删除对象后使用该对象。
另一种可能性是缓冲区溢出。它可以是同一堆栈或堆附近的任何对象。
捕获罪魁祸首的一个很好的方法是设置一个在内存更改时触发的调试器断点。当对象仍然完好时,设置断点。然后等待一些代码写入该内存位置。这应该会暴露你的错误。
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.
如果您从 VS 调试器获取信息,我不会相信它告诉您有关发布 DLL 的信息。只有调试 DLL 才能真正信任调试器。
如果程序输出告诉您这一点,那么情况就不同了——在这种情况下,您没有提供足够的信息。
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.
您是否将发布 DLL 与调试应用程序混合在一起?
否则听起来像是内存损坏,尽管我不能肯定地说。
这些在某些情况下似乎工作正常,因为它们是未定义的行为,并且只有在释放模式下它们才会爆炸。
Are you mixing a release DLL with a debug app?
Otherwise it sounds like memory corruption, although I can't say for sure.
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.
我在 g++ 上遇到了完全相同的问题,我通过删除之前的 pragma 段落中的 pragma 解决了这个问题。尽管代码是正确的,但我想知道这是否是在某些情况下使用 stl::map 时出现的平台上的编译器错误。
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.
只是举一个内存损坏的具体例子:
我不小心定义了对成员变量的引用,而不是成员变量本身。它初始化得很好,但是一旦 static_init() 的范围离开,映射就会被销毁,并且引用将在调试中显示为“std::map with 140737305218461 elements”(漂亮打印)或类似的内容指向现在未分配的内存(或更糟)。
谨防意外引用!
Just to give a concrete example for the memory corruption:
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!