C ++:程序退出时静态原语是否无效?

时间:2008-11-20 15:01:01

标签: c++ memory-management static

假设我有这样的功能:

MyClass &MyFunction(void)
{
  static MyClass *ptr = 0;
  if (ptr == 0)
    ptr = new MyClass;
  return MyClass;
}

问题是在程序退出时间,ptr变量是否会变为无效(即该ptr的内容是否被现有进程清理)?我意识到这个函数泄漏了,但它只是一个简单的例子。

同样的问题也适用于除指针之外的其他原语。如果我有一个静态整数,该整数的值是否始终在退出时保持不变或由于静态销毁订单问题而变化?

编辑:

为了澄清,我想知道静态指针(或任何其他基本类型,如int或float)的内容实际发生了什么,而不是它指向的内存。例如,假设ptr指向某些内存地址,我想在其他静态类的析构函数中检查它。我可以依赖ptr内容不会改变的事实(即在静态破坏过程中指针值不会被清除)吗?

谢谢, 乔

5 个答案:

答案 0 :(得分:6)

当您处理退出时,操作系统将释放分配给它的所有内存页(其他人可能正在使用的模数共享内存页)。

但是,正如其他人指出的那样,MyClass的析构函数永远不会被调用。 ptr指出的价值也没有改变。如果你有一个值为123的静态int,那么它的值将保持123到过程'生命周期的最后。

答案 1 :(得分:4)

在现代操作系统中,应用程序的所有内存都分配在特定于该应用程序的“堆”上。当应用程序退出时,将释放该堆中的所有内存。

因此,内存将被释放,但是:永远不会调用MyClass的析构函数。如果析构函数负责释放任何非内存资源(文件系统锁是一个常见示例),这可能是一个问题。

答案 2 :(得分:3)

要回答您更新的问题,我会说是:您可以依赖静态销毁过程中剩余的静态指针的。它指向的内存可能已被释放,但指针本身的值应保持不变,除非另一个静态类的析构函数对其进行更改。

答案 3 :(得分:3)

回答你的问题:

'imagine that the ptr points to some memory address which I want to check in the destructor of some other static class'

答案是肯定的。
您可以看到指针的值(地址) 如果您没有在指针上调用delete,则可以查看内容。

静态函数变量的行为与静态类变量和全局变量(又名非局部静态)的行为相同,因为析构函数将以创建的相反顺序调用。整数,浮点数和指针(POD)没有析构函数,因此在删除进程之前不会发生任何事情。

POD对象:可以通过从其他对象(甚至是全局s)的析构函数引用来安全地获取数据。

其他静态对象(即带有析构函数的对象):在一般情况下,在main()退出后访问这些对象是不安全的,因为不知道破坏的顺序(它与创建顺序相反) ,但创作的顺序很复杂,请参阅:Construction Order)。可以这样做,但你必须采取明确的预防措施,以确保对象仍然存在。

注意:非本地静态:

内存将永远存在,在调用析构函数后对象将无效(注意POD没有析构函数)。

注意:堆栈:

仅在声明它们的范围之前有效。
弹出堆栈后,如果您尝试访问它,可能会丢弃它所在的内存页面,从而导致SEG错误。

注意:堆:

有效,直到您在分配它的指针上调用delete 一旦指针被删除,该值可能是随机的,因为它可能被重用。 可能还会删除内存所在的页面。对删除页面的任何访问都会导致SEG错误。

答案 4 :(得分:1)

简短回答是“否”:你的指针在程序退出时不会“变为无效”。即指针值不会自动重置为null,并且不会自动调用它指向的MyClass对象的析构函数。

这是因为指针是“基本类型”,即不是对象。

如果你有一个非局部(即全局或静态)变量是一个对象,那么规则是不同的:当程序通过调用exit()或从返回来终止时,将调用对象的析构函数。主功能。如果程序通过调用abort()终止,则不会调用它。