根据微软的文档,调用 exit() 时哪些变量会被销毁?

问题描述 投票:0回答:1

我试图找出

terminate()
exit()
abort()
之间的区别,以及 Microsoft 的 C++ 程序终止 文档出现在我的 Google 搜索中,比较了
exit
abort
atexit

我读了比较

exit
abort
的第一部分,它很有意义:

exit 和 abort 的区别在于 exit 允许 C++ 进行运行时终止处理(调用全局对象析构函数)。 abort 立即终止程序。 abort 函数绕过已初始化全局静态对象的正常销毁过程。它还绕过使用 atexit 函数指定的任何特殊处理。

然后,还有

return
exit
与这个示例代码的比较以及相应的解释:

// return_statement.cpp
#include <stdlib.h>

struct S 
{
    int value;
};

int main()
{
    S s{ 3 };

    exit( 3 );
    // or
    return 3;
}

前面示例中的 exit 和 return 语句具有类似的行为。两者都会终止程序并向操作系统返回值 3。不同之处在于 exit 不会破坏自动变量

s
,而 return 语句则会破坏。

  1. 我以为当

    s
    被调用时,
    exit()
    也会被销毁。是我理解错了,还是有什么错误?

  2. 如果

    s
    没有被销毁,我们如何从堆栈中回收这块内存?如果
    s
    在堆上,我们也会泄露这段内存吗?

我并不是在寻找特定于 Microsoft 的解决方案。我刚刚找到源代码并意识到 Microsoft 确实为像我这样的初学者提供了很好的文档。

c++ return destructor exit
1个回答
0
投票

全局对象被销毁;本地对象不是。例如这段代码:

#include <stdio.h>
#include <stdlib.h>

class Foo {
    char const *s;
public:
    Foo(char const *s) : s(s) {}
    ~Foo() { fprintf(stderr, "cleaning up %s object\n", s); }
};

Foo f("global");

int main() {
    Foo g("local");
    exit(0);
}

产生此输出:

cleaning up global object

Godbolt 直播

对于任何可能想知道为什么这样写/它是如何工作的人:

  • 使用
    fprintf
    代替
    std::cerr
    ,因为当
    f
    被销毁时,我们不知道
    std::cerr
    是否还存在。
  • 所有字符串文字都有静态存储持续时间,因此当
    f
    g
    被销毁时,它们尝试打印的字符串文字仍然存在(尽管它可能看起来像是
    g
    使用的字符串文字)从
    main
    退出时被摧毁。
© www.soinside.com 2019 - 2024. All rights reserved.