如果在C++中,具有自动存储的对象没有通过调用exit来销毁,那么在离开程序后,这些对象会发生什么

If in C++ objects with automatic storage are not destroyed by calling exit, what happens with this objects after leaving the program?

本文关键字:对象 程序 离开 什么 调用 C++ 存储 如果 exit      更新时间:2023-10-16

在这个网站(cplusplus.com)上,我读到具有自动存储的对象不会通过调用exit()来销毁。这是否意味着内存会泄漏?我知道,当你到达自动变量作用域的末尾时,它们会被销毁,但在这种情况下,这是否意味着我们没有到达作用域的末端,只是离开了程序?


我很好奇在论坛上发现的这个例子中,内存会发生什么:

C++代码

#include <cstdlib>
#include <iostream>
struct C
{
~C()
{
std::cout<<"X"<<std::endl;
}
};
void f()
{
C c;
exit(1);
}
int main()
{
f();
}

这里没有输出"X",所以没有调用析构函数。那么我们可以说这是内存泄漏吗?


编辑:

感谢您的回复。但我想澄清其他一些事情。假设操作系统在程序完成后不会释放内存,这是否意味着exit()调用具有自动存储的对象后会导致内存泄漏(因为它不会被破坏)?或者,它可能只在使用运算符new从堆中分配内存时发生?

也许我把这个问题表述得不太清楚,但我想知道具有自动存储的对象在任何情况下是否被破坏,即使程序在块结束前没有到达,并被exit()调用中断。

正常的内存分配不会泄漏,因为当进程退出时,其所有内存页都会被清除。然而,在其析构函数中清理独立于进程的外部资源(如文件)的对象可能会泄漏它们,例如:

class TempFile {
public:
TempFile() { /* create a file on disk */ }
~TempFile() { /* delete the file from disk */ }
}
void foo() {
TempFile tf;
exit(0);
}

这通常是内存泄漏;不过,现代操作系统会清除它。

我建议阅读下面的公认答案,因为我们需要知道你所说的"内存泄漏"是什么意思:

Valgrind 检测到仍然可到达的泄漏

根据C++98§18.3/8

exit时,只销毁静态对象,然后执行atexit处理程序,刷新和关闭打开的流,并删除由tmpfile创建的文件本地自动对象不会被销毁。

http://en.cppreference.com/w/cpp/utility/program/exit
堆栈未展开:具有自动存储的变量的析构函数持续时间不称为

#include <cstdlib>
#include <iostream>
struct C
{
C( const std::string &name ) :
m_name( name ) { }
~C()
{
std::cout<< m_name << " destructor" <<std::endl;
}
std::string m_name;
};
static C c1( "Static C" );
void f()
{
C c( "Local C" );
exit(1);
}
int main()
{
f();
}

告诉您的只是没有调用析构函数。并不是说内存泄漏。