【问题标题】:When is memory deallocated in relation to static variables? [duplicate]何时释放与静态变量相关的内存? [复制]
【发布时间】:2013-08-02 19:54:03
【问题描述】:

我想知道是否有人可以阐明 C++ 中的内存释放过程。

如果我有一个我声明为静态的结构,那么它的构造函数是首先要执行的,而它的析构函数是最后要执行的:

struct initializer execute_before_and_after_main {
     initializer() { init(); }
     ~initializer() { cleanup(); }
}
static initializer execute_around_main;

然后我有类似的东西:

class my_class {
    my_object objects[100];
}
extern my_class gobal_my_class;
my_class global_my_class;

这里 main 并不重要:

int main (int argc, char* argv[]) {
    ....
} 

当调用cleanup() 时,objects 数组现在是否包含已释放/无效的内存?是否有 c++ 在这里实现的标准初始化/销毁序列,有人可能会指出我?

谢谢

编辑:我知道这种类型的代码可能不是最佳实践,但我仍然想知道行为是否已定义。

【问题讨论】:

  • 是时候熟悉storage duration
  • @CaptainObvlious 哈哈,我正准备在我的答案中添加相同的链接
  • 对于具有静态存储持续时间的对象的初始化和销毁​​没有标准定义的顺序;这被称为static initialization order fiasco
  • @Praetorian:是的,部分存在。
  • @MooingDuck 你指的是如果它们在同一个TU中定义,它们将按声明顺序初始化?如果是这样,标准中是否真的提到了这一点?它可能只是每个实现都会做的事情之一,但不是强制性的......我不知道......

标签: c++


【解决方案1】:

静态和全局变量都有static storage duration,这意味着它们在程序结束时被释放。通过阅读其中一个副本,我发现如果代码都在同一个翻译单元(你的翻译单元是)中,那么具有静态存储的对象将以相反的构造顺序被破坏。如果对象位于不同的翻译单元中,则您无法保证任何事情。

调用 cleanup() 时,对象数组现在是否包含已释放/无效的内存?

是的,但这并不重要,因为它只会在对象超出范围时调用

global_my_class 在 execute_around_main 之前被破坏了吗?

是的,全局我的类首先被破坏,因为它是最后初始化的

【讨论】:

  • "C++ 在这里实现的初始化/销毁的标准序列" 程序结束时它们都被释放的事实并不能解决global_my_class 的内存是否有效的问题在execute_around_main被破坏期间。
  • @MooingDuck 所以,如果我只回答一半的问题,你觉得有必要投反对票,我会尝试修正答案,但我不是 100% 清楚他想问什么
  • "调用 cleanup() 时,对象数组现在是否包含已释放/无效的内存?" -> “global_my_classexecute_around_main 之前被破坏了吗?”
  • @MooingDuck 第二部分很难回答,因为他没有把它写成一个连续的文件,但我认为 global_my_class 首先被破坏,因为它是在之后构建的
  • @MooingDuck 我试图解决您的所有问题,请随时纠正我
猜你喜欢
  • 2011-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-18
  • 2021-11-07
  • 2011-12-12
  • 1970-01-01
  • 2011-07-30
相关资源
最近更新 更多