[英]Can static allocated memory become invalid during static deinitialization?
说我已经定义了一个像这样的变量(C ++):
static const char str[] = "Here is some string data";
而且我有一个静态分配的类实例,该实例在其析构函数中引用此数组,这会出错吗? 例如, str变量可能以某种方式变得无效吗?
class A {
~A() {
cout << str << endl;
}
};
static A a;
我的假设是它不会出错,但是我可以在任何地方清楚地指出它。 我想肯定知道这一点。 我的假设是,我们无法预测调用静态分配的对象的析构函数的顺序,但是直到该过程被拆除之前,才不会真正释放数据本身。 指向POD的指针应该是安全的,但不是对象实例。
含义例如:
static const QString str = "Here is some string data";
要么
static const std::string str = "Here is some string data";
无法安全地在A的析构函数中使用,因为它们都在堆上分配了其字符串数据,并且在调用A的析构函数之前,析构函数可能会释放它们。
我的假设是正确的,C ++标准中是否有任何部分对此进行了解释,或者是否与其他可以验证这一点的机构建立了链接?
始终自动定义自动,全局和静态对象的析构函数的调用顺序:这与构造函数的调用顺序相反。 因此,如果对象A
引用了对象B
并且B
在 A
之前构造 ,则可以确保B
在 A
之后被破坏 。 这给我们留下了构造函数顺序的问题。
这是我记得的内容:
main()
之前构造的。 我对其中一些内容有些模糊,因此,如果您认为这不正确,请更正我。
好吧,我尝试自己阅读C ++标准以找到一些答案。 从答案中可以看出,关于构造对象和分配对象之间的区别存在很多困惑。
从标准:
3.6.2初始化非本地对象
具有静态存储持续时间(3.7.1)的对象应在进行任何其他初始化之前进行零初始化(8.5)。 可以使用常量表达式(5.19)初始化具有静态存储持续时间的引用和具有静态存储持续时间的POD类型的对象。 这称为常量初始化。 零初始化和常量初始化合在一起称为静态初始化。 所有其他初始化是动态初始化。 静态初始化应在任何动态初始化发生之前执行。 对象的动态初始化是有序的或无序的。
我对此的解释是,始终保证在运行任何构造函数之前已设置const char [] 。
3.6.3终止静态存储持续时间的初始化对象的析构函数(12.4)(在块作用域或命名空间作用域声明)是从main返回和调用std :: exit(18.3)的结果。 这些对象按照其构造函数完成或动态初始化完成的相反顺序销毁。 如果对象是静态初始化的,则该对象的破坏顺序与该对象被动态初始化的顺序相同。
据我所知,具有常量表达式的POD类型将在任何对象类型之前进行初始化,并在任何对象类型之后进行销毁。 这意味着在它们无效时,将不会运行任何可以访问它们的代码。
哪个应该解释为什么Google的C ++代码标准说您应该只使用带有常量表达式的POD类型。 :
结果,我们只允许静态变量包含POD数据。 此规则完全禁止使用vector(改为使用C数组)或string(使用const char [])。
如果我没记错的话,全局对象初始化未在标准中定义(或定义不充分),这使得全局对象难以相互引用。
如果您想确定初始化顺序,请在其中使用带有静态对象的全局函数,然后将其返回。 现在,您将保证在第一个函数调用时将初始化静态对象。
一旦脱离main(),销毁将在应用程序末尾发生。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.