c++: "double free or corruption"用于全局外部变量?

标签 c++ global-variables constants extern

我有兴趣在整个程序中只使用一个全局变量。所以我认为实现这一点的最好方法是像这样在头文件中定义它:

extern const std::string CONST_STR = "global string";

但这导致了“双重释放或损坏”运行时错误。 删除 extern 使问题消失。

  1. 谁能解释一下这种行为?
  2. AFAIK,如果没有 extern 定义,每个翻译单元都会有一个 CONST_STR,难道没有办法获得一个完全 const 的全局变量吗?

最佳答案

解决第一部分和有关丢失 extern 的其他问题。

const std::string CONST_STR = "global string";

根据 C++ 规则,这等同于说:

static const std::string CONST_STR = "global string";

如果这是在包含文件中,您将在每个翻译单元 (TU) 中创建不同的字符串。它们本身都可以正常工作,但假设您还在同一 header 中添加了一个函数:

inline void foo() { std::cout << CONST_STR; }

如果<<运算符通过 const& 获取字符串, 在每个 TU 中,它将绑定(bind)到一个单独的字符串。因此违反了“一个定义规则”并使您陷入未定义的行为(UB)。在实践中它很可能有效,但它仍然是 UB。

原文extern形式与此类似,因为看起来相同的字符串文字在不同的 TU 中也是分开的。

如果你只说extern没有初始化器,它是一个声明,将由链接器解析为单个定义。如果您使用初始值设定项,那么它就是一个定义。因此,该对象再次在每个 TU 中创建,但使用公共(public)名称,期望其他 TU 访问它。由于您必须确保实际只提供一个定义,因此实现免除了责任。

不幸的是,单一定义规则太容易被打破,而且它的大多数形式明确允许实现不发出任何诊断。实际上,链接器只是从池中随机选择一个定义。 double free 可能是由于发出 _atstart 引起的和 _atexit构造函数和析构函数调用的条目,对象本身融合为一个,然后获得与 TU 一样多的构造函数和析构函数调用。

对于实现来说,一切都是公平的,至于 UB,一切皆有可能。

关于c++: "double free or corruption"用于全局外部变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17344999/

相关文章:

C++)为什么 const int*& 参数不能采用 int* 参数?

c++ - 如何进行模板类型参数特化?

c++ - 除非将操作添加到工具栏,否则 Qt5 无法识别快捷方式

c++ - 我在哪里处理特定 mfc 编辑控件的 "Enter"键事件?

java - 从随机的三元组字母表中猜一个词

python - 全局字典,不是所有线程都向它添加键?

php - 存储站点全局变量

python - 当我将其设置为全局变量时在 python 中赋值之前引用的局部变量

c++ - 'strcpy' : cannot convert parameter 2 from 'WCHAR *' to 'const char *

c - C 中的换行常量