我在模板类函数中有一个静态变量,如下所示:
template<class T>
struct builder
{
static T* buildOrGet()
{
static T* built = nullptr;
if(built == nullptr) built = new T;
return built;
}
};
以及代码中的其他地方带有构造函数的全局变量。
static SomeClass global_var;
起初我不知道发生了什么,但built
变量在程序的某一点无缘无故地被破坏了。然后,我在&built
上的visual studio中添加了一个4字节的数据断点,以查看谁在built = new T;
之后压碎了它的内存,实际上它是在初始化{{1}的成员时在C ++动态初始化程序期间在global_var
构造函数中。
代码在一个DLL中,由exe自动加载,具体取决于它。
它就像SomeClass
内存重叠global_var
内存,这非常奇怪。
我真的不明白为什么以及如何发生这种情况除了Visual Studio 2015中的错误,你能帮助我吗?
答案 0 :(得分:0)
我找到了解决方案:
实际上我在我的dll的不同翻译单元中有多个global_var
具有相同的名称,但它们没有相同的类型(假设另一个具有int
类型)。
在这种情况下(这对我来说很奇怪,因为它们是'静态'),链接器只保留一个并为所有变量使用相同的内存(它保存在int
一个)。
这就是出错的地方......我仍然为上面提到的global_var
调用了SomeClass构造函数,但它的内存不是sizeof(SomeClass)
,而是sizeof(int)
和这是溢出发生的地方。
对我来说这是一个错误,因为链接器应该注意到我这些具有不同类型的同名变量或/并且应该避免在与构造的内存不匹配的变量上调用构造函数。
解决方案是:永远不要在不同的翻译单元中声明两个具有相同名称的静态变量,只有一个会存活,你无法猜出哪一个。