这一定是我做了一些愚蠢的事情,但之前有人看到过这种行为:
我有一个类定义如下的类成员的地图:
std::map <const std::string, int> m_fCurveMap;
在debugging中都performance良好,但在发布模式下全部出错。 地图被初始化为一些疯狂的数字: 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。
如果你之前看到过这种疯狂的话,请帮助它把我逼疯。 🙂
非常感谢,马克
这发生在我身上很多次。 虽然很难说你的情况,但很可能的原因是你在不同的项目之间有不同版本的C运行时库。 在编译器设置中检查您的“代码生成”选项卡,以确定它们是否相同。
实际发生的事情是不同版本的C运行时库以不同的方式实现STL容器。 然后,当不同的项目试图相互交谈时,std :: map(例如)的含义已经改变,不再是二进制兼容的。
奇怪的行为很可能是某种堆腐败,或者如果它作为参数传递给函数,堆栈损坏。
问题是某种内存损坏。
我经常在C ++项目中看到的一个错误就是在删除一个对象后使用它。
另一种可能性是缓冲区溢出。 它可以是堆栈上或附近的任何对象。
捕捉罪魁祸首的一个很好的方法是设置一个调试器断点,引发内存变化。 当对象仍然好时,设置断点。 然后等到某些代码写入该内存位置。 这应该揭示你的错误。
如果你从VS调试器获得你的信息,我不会相信它是告诉你一个发布DLL。 调试器只能被调试DLL真正的信任。
如果程序输出告诉你这个,那就不一样了 – 在这种情况下,你没有提供足够的信息。
你是否将一个发布DLL与一个调试应用程序混合?
否则,这听起来像内存腐败,虽然我不能肯定地说。
其中任何一个在某些情况下都可以正常工作,因为它们是未定义的行为,只有在释放模式下才会爆炸。
我在g ++上遇到了完全相同的问题,通过在前面的pragma段落中删除杂注来解决问题。 尽管代码是正确的,但我不知道这是否是在某些情况下使用stl :: map时出现的平台上的编译器错误。
#pragma pack(push,1) xxxx #pragma(pop)
只是为了给内存腐败的一个具体的例子:
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; };
意外的是,我定义了一个ref的成员变量,而不是成员变量本身。 它被初始化好了,但只要static_init()的范围被留下,地图就被销毁,ref会在调试中显示为“std :: map with 140737305218461 elements”(漂亮地打印)或类似的指向现在未分配的(或更糟)。
谨防意外的参考!