在 EXIT_FAILURE 发生时清理字符串,而不是 exit(0)

Cleaning up strings when EXIT_FAILURE occurs, instead of exit(0)

所以当 exit(0) 发生时,字符串被神奇地清理了,并且 valgrind 报告没有泄漏。

exit(EXIT_FAILURE) 发生时,它可以在多个点发生,valgrind 报告 "possible leaks" 我创建的一堆 C++ 字符串。

当我知道 exit_failure 发生时如何清理它们?

编辑:我指的是我这样创建的字符串:

第 22 行 string include = "#include";

瓦尔格林德:

==42430== 
==42430== HEAP SUMMARY:
==42430==     in use at exit: 100,201 bytes in 22 blocks
==42430==   total heap usage: 33 allocs, 11 frees, 101,121 bytes allocated
==42430== 33 bytes in 1 blocks are possibly lost in loss record 6 of 22
==42430==    at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==42430==    by 0x4EF2568: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==42430==    by 0x4EF2676: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==42430==    by 0x4EF42D5: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==42430==    by 0x401C5A: processOneFile(std::istream&, std::ostream&, Node*, std::string) (include.cc:22)
==42430==    by 0x402497: processOneFile(std::istream&, std::ostream&, Node*, std::string) (include.cc:99)
==42430==    by 0x402C82: main (include.cc:172)

这听起来不像是内存泄漏。一旦进程退出,OS 将回收与其关联的堆内存。当您释放内存时,您通常所做的是调整应用程序本地的堆分配记帐信息。

这是一条失控的评论。

总而言之,内存在这里不是什么大问题。该程序因 exit 而终止,因此泄漏最多为几毫秒。伊皮!

使用 exit 时您真正需要注意的是所有那些可能完成了重要事情而不是 运行 的析构函数,例如将数据刷新到屏幕或文件、礼貌地挂断网络连接以及释放资源不受 OS 管理。除非程序必须用 headsman 的斧头的微妙之处立即终止,否则 return 返回 main 并正常退出。

如果这不是一个选项,或者因为这是 C++ 并且任何调用 exit 的东西都应该是非常例外的,throw 一个例外并获得所有堆栈展开的好处。

@user 我必须查看您的代码才能提出好的建议。您可以使用像 throw "Oh crap!"; 这样简单的东西进行测试,但通常我会像这样扩展 std::exception 东西:

#include <iostream>
#include <exception>
#include <string>
class Failure: public std::exception
{
private:
    std::string mErrMsg;

public:
    Failure(std::string errMsg):mErrMsg(errMsg)
    {
        // does nothing
    }
    const char* what() const noexcept
    {
        return mErrMsg.c_str();
    }
};

然后在 exit 的位置,我输入:throw Failure("description");。例如,

void function()
{
    // does stuff
    if (bad_stuff_happened)
    {
        throw Failure("description of the bad stuff that happened");
    }
}

然后我将 main 或其他一些低级函数包装在 try/catch 块中以记录错误。这是 main:

int main()
{
    try
    {
        function();
        return EXIT_SUCCESS;
    }
    catch (Failure &excp)
    {
        std::cerr << excp.what();
        return EXIT_FAILURE;
    }
}

这个输出是

description of the bad stuff that happened

在标准错误中。

我不会 throw exit(0),我也不建议你这样做。我也不推荐exit(0)。一个好的程序结果应该是非常普遍的,如在非特殊情况下一样,并通过常规代码流进行处理。