在 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)
。一个好的程序结果应该是非常普遍的,如在非特殊情况下一样,并通过常规代码流进行处理。
所以当 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)
。一个好的程序结果应该是非常普遍的,如在非特殊情况下一样,并通过常规代码流进行处理。