c++ - 处理的异常可能导致内存泄漏? (使用调用 exit() 的异常处理。)

标签 c++ exception memory-leaks valgrind

我正在开发一个 C++ 应用程序(大学的 OpenSSL 作业),并且我正在通过 valgrind 运行它,就像一个人所做的那样。当程序由于无效输入而失败时,我注意到一些相当奇怪的输出:

==1739== HEAP SUMMARY:
==1739==     in use at exit: 588 bytes in 6 blocks
==1739==   total heap usage: 52 allocs, 46 frees, 99,206 bytes allocated
==1739== 
==1739== 44 bytes in 1 blocks are possibly lost in loss record 3 of 6
==1739==    at 0x483BE63: operator new(unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==1739==    by 0x4C20378: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28)
==1739==    by 0x4C03187: std::logic_error::logic_error(char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28)
==1739==    by 0x4C0325C: std::invalid_argument::invalid_argument(char const*) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28)
==1739==    by 0x10FB6D: lab2::cryptoEngine::CBCCryptoEngine::encrypt() (CBCCryptoEngine.cpp:39)
==1739==    by 0x10E355: main (main.cpp:135)
==1739== 
==1739== 144 bytes in 1 blocks are possibly lost in loss record 4 of 6
==1739==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==1739==    by 0x4BDB1F3: __cxa_allocate_exception (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28)
==1739==    by 0x10FB5B: lab2::cryptoEngine::CBCCryptoEngine::encrypt() (CBCCryptoEngine.cpp:39)
==1739==    by 0x10E355: main (main.cpp:135)
==1739== 
==1739== LEAK SUMMARY:
==1739==    definitely lost: 0 bytes in 0 blocks
==1739==    indirectly lost: 0 bytes in 0 blocks
==1739==      possibly lost: 188 bytes in 2 blocks
==1739==    still reachable: 400 bytes in 4 blocks
==1739==                       of which reachable via heuristic:
==1739==                         stdstring          : 44 bytes in 1 blocks
==1739==         suppressed: 0 bytes in 0 blocks
==1739== Reachable blocks (those to which a pointer was found) are not shown.
==1739== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==1739== 
==1739== For lists of detected and suppressed errors, rerun with: -s

导致它的代码只是在输入文件无效时抛出的常规异常。像这样正确捕获异常:

try {
    engine.encrypt(bad_argument); // Placeholder. The exception type stands, though...
}
catch (const std::invalid_argument &e) {
    std::cerr << "Exception while encrypting file: " << e.what() << std::endl;
    delete (engine);
    exit(EXIT_FAILURE);
}

我不是 100% 确定它是什么意思,如果它甚至是一个问题,因为操作系统无论如何都会回收内存。但我以前从未见过这种东西,想检查一下。

所以,我的问题是,它是由什么引起的?我应该修理它吗?如果是,怎么办?

最佳答案

std::logic_error's constructor为“解释性字符串”分配的内存。这是异常处理程序中的 what() 返回给您的(std::invalid_argument 继承自 std::logic_error)。

观察回溯显示构造函数重载,该重载采用 const char * 作为参数。如果文字 const char * 被藏起来,并从 what() 返回给您,那将是可以接受的。然而,构造函数被编码为复制“解释字符串”以使其内容完全由构造的 std::logic_error 拥有的原因有很多。

您的异常处理程序静静地调用了 exit() 并且进程终止了。此时 valgrind 通知您上述分配的内存没有被破坏。这是真的,内存没有被释放。

如果您的异常处理程序的范围自然结束(不调用 exit()),std::logic_error 的析构函数将删除分配的内存,每个人都会从此过上了幸福的生活。

TLDR:这只是技术性内存泄漏。这在技术上是正确的,只是因为地毯是通过调用 exit 从过程中拉出来的。

请注意 valgrind 说的是“可能”而不是“肯定”。毫无疑问,当 valgrind“肯定”声称存在内存泄漏时,您会发生内存泄漏。如果它只是“可能”,那么可能存在也可能不存在真正的内存泄漏。

关于c++ - 处理的异常可能导致内存泄漏? (使用调用 exit() 的异常处理。),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72005386/

相关文章:

c# - EmguCv.CV.CvInvoke 抛出的 EmguCv TypeInitializationException

c++ - 函数正确执行后如何修复 Core Dumped 错误?

c++ - C++/Qt 应用程序的内存使用情况

c++ - 结构的 QVector - 没有合适的默认构造函数可用

C++模板模板推断类型参数

c++ - VS2010 未在预处理器条件下正确处理 "includes"

php - Symfony ExceptionHandler 抛出关于自身的错误

php - 在维护 View 页面下显示站点,了解laravel应用程序中的所有错误/异常

AngularJS - $destroy 是否删除事件监听器?

您可以使用 gdb(或其他工具)从核心文件中找到内存泄漏吗?