模板类函数中的静态变量被全局静态变量覆盖
Static variable in template class function overwritten by global static variable
在模板类函数中有一个静态变量:
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;
之后谁破坏了它的内存,实际上它是在初始化global_var
成员时的c++动态初始化期间,在SomeClass
构造函数中。代码在dll中,由依赖它的exe自动加载。这就像global_var
内存和built
内存重叠,非常奇怪。
我真的不明白为什么会发生这种情况,除了Visual Studio 2015中的一个bug,你能帮助我吗?
我找到了解决方案:事实上,我在我的dll的不同翻译单元中有多个具有相同名称的global_var
,但它们没有相同的类型(假设另一个具有int
类型)。
在这种情况下(这对我来说很奇怪,因为它们是'静态'),链接器只是保留一个,并为所有变量使用相同的内存(它在这里保留了int
一个)。
这就是它出错的地方…我上面提到的global_var
仍然调用SomeClass构造函数,但它的内存不是sizeof(SomeClass)
,而是sizeof(int)
,并且这就是溢出发生的地方。
对我来说,这是一个bug,因为链接器应该注意到这些具有不同类型或/的同名变量,并且应该避免在与构造内存不匹配的变量上调用构造函数。
解决方案是:永远不要在不同的翻译单元中声明两个具有相同名称的静态变量,只有一个会存活,并且您无法猜测是哪一个。
相关文章:
- 在 .h 文件中的类中声明静态变量和在.cpp文件中声明"global"变量有什么区别
- 模板基类中的静态变量
- 类和静态变量
- 不同作用域中的静态变量和全局变量
- 静态变量声明和定义
- 是否可以依赖函数范围的静态变量来执行程序关闭期间调用的方法?
- 在类中继承静态变量?
- "local scope"中的 C++ 初始化静态变量
- 使用静态变量的递归调用的不同输出
- 复制文件流C++静态变量
- 跨模板化函数编译的静态变量
- C++编译器是否优化了顺序静态变量读取?
- C++,每个循环初始化一个新的静态变量
- (为什么)我们可以在初始化中将非静态类成员分配给静态变量吗?
- 这些语句是否等效(静态变量、常量变量和泛型)
- 程序如何知道静态变量是否需要初始化?
- 类外的静态变量实例化
- 无法解析静态变量
- 函数局部静态变量:从性能角度来看的优点/缺点
- 访问从 CPP 文件到其他头文件的静态变量