简体   繁体   English

模板类函数中的静态变量被全局静态变量覆盖

[英]Static variable in template class function overwritten by global static variable

I have a static variable in a template class function like this : 我在这样的模板类函数中有一个静态变量:

template<class T>
struct builder 
{
    static T* buildOrGet() 
    { 
        static T* built = nullptr;
        if(built == nullptr) built = new T;
        return built;
    }
};

and somewhere else in the code a global variable with a constructor. 在代码的其他位置带有构造函数的全局变量。

static SomeClass global_var;

At first I didn't know what happened but the built variable was corrupted at a certain point of the program for no reason. 刚开始我不知道发生了什么,但是built变量在程序的某个点被无缘无故损坏了。 Then, I added a 4-bytes data breakpoint in visual studio on &built to see who crushed its memory after built = new T; 然后,我在&built上的Visual Studio中添加了一个4字节的数据断点,以查看谁在built = new T;之后破坏了它的内存built = new T; , and in fact it is during the C++ dynamic-initializer when initializing members of global_var , in the SomeClass constructor. ,实际上是在C ++动态初始化程序中,在SomeClass构造函数中初始化global_var成员时。 The code is in a dll, auto loaded by an exe depending on it. 该代码位于dll中,并由exe自动加载。 It is like global_var memory overlaps built memory, which is very weird. 就像global_var内存与built内存重叠一样,这很奇怪。

I really don't understand why and how this could happen except a bug in Visual Studio 2015, can you help me ? 除了Visual Studio 2015中的错误外,我真的不明白为什么以及如何发生这种情况,您能帮我吗?

I found the solution : In fact I have multiple global_var with the same name in different translation units of my dll but they don't have the same type (let's say another has int type). 我找到了解决方案:实际上,我在dll的不同转换单元中有多个具有相同名称的global_var ,但它们的类型不同(假设另一个具有int类型)。

In this case (which is weird to me because they are 'static'), the linker just keep one and use the same memory for all the variables (it kept here the int one). 在这种情况下(对我来说很奇怪,因为它们是“静态的”),链接器仅保留一个,并对所有变量使用相同的内存(此处保留为int )。

This is where it goes wrong... The SomeClass constructor is still called for the global_var I mentioned above but its memory is not sizeof(SomeClass) , but sizeof(int) , and this is where the overflow happens . 这是哪里出错了... SomeClass构造函数仍被我上面提到的global_var调用,但是它的内存不是sizeof(SomeClass) ,而是sizeof(int)这就是溢出发生的地方

To me it's a bug, because the linker should have noticed me about these homonymous variables with different types or/and should have avoid to call a constructor on a variable which doesn't match the constructed memory. 对我来说,这是一个错误,因为链接器应该已经注意到有关这些具有不同类型的同形变量的信息,或者/并且应该避免在与构造的内存不匹配的变量上调用构造函数。

The solution is : never declare two static variable with the same name in different translation units, only one will survive and you cannot guess which one. 解决方法是:永远不要在不同的翻译单元中声明两个具有相同名称的静态变量,只有一个可以生存,并且您无法猜测哪个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM