首页 >后端开发 >C++ >为什么在 C 中包含 `` 会导致 Valgrind 的'Still Rereachable”警告?

为什么在 C 中包含 `` 会导致 Valgrind 的'Still Rereachable”警告?

Linda Hamilton
Linda Hamilton原创
2024-12-03 18:35:13688浏览

Why Does Including `` in C   Cause Valgrind's

在 C 中包含标准库头文件和 Valgrind 警告

简介:

本文深入探讨了为什么简单地包含 的问题; C 程序中的标准库头可以在 Valgrind 中触发仍然可达的警告,即使该库中的任何对象都没有在程序中分配。

程序和 Valgrind 输出:

提供的代码片段是一个简单的“hello world”程序,其中包括 标头但不执行任何分配:

#include <iostream>

int main() {
  return 0;
}

通过 Valgrind 运行此程序并启用泄漏检查和跟踪源会显示以下输出:

==27671== Memcheck, a memory error detector
... (output truncated)
...
==27671== 72,704 bytes in 1 blocks are still reachable in loss record 1 of 1
==27671==    at 0x4C2AB9D: malloc (vg_replace_malloc.c:296)
==27671==    by 0x4EC060F: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
... (output truncated)

这表明 72,704 字节仍然是尽管没有在程序中显式分配任何内存,但仍可访问。

Valgrind 的行为:

虽然 Valgrind 的警告可能令人担忧,但重要的是要了解这是 C 程序的常见行为。 C 标准库的许多实现都使用自己的内存池分配器,这些分配器为被破坏的对象分配内存并在以后重用它们。这种优化的内存管理技术减少了内存开销并提高了性能。

但是,由于 Valgrind 的运行假设是所有分配的内存都应在程序终止时返回到操作系统,因此它将这些池所持有的内存报告为仍然可达。这不一定是程序或 Valgrind 中的错误,而是期望的差异。

禁用 C 库优化:

如果您希望使用 Valgrind 消除仍然可达的警告,您可以通过修改编译器设置禁用STL(标准模板库)内存池。以下是一些方法:

使用 __USE_MALLOC:

对于 GCC 版本 2.91 到 3.1,您可以使用 -D__USE_MALLOC 编译程序,强制 STL 使用 malloc 并立即释放内存。不过,这个选项在 GCC 3.3 及更高版本中已被删除。

使用环境变量:

对于 GCC 3.2.2 及更高版本,您可以在运行程序之前设置环境变量 GLIBCPP_FORCE_NEW。对于 GCC 3.4 及更高版本,环境变量名称为 GLIBCXX_FORCE_NEW。

使用编译器标志:

对于较新的编译器,您可以使用 -fno-optimize-sibling-calls 标志来禁用同级调用优化,其中包括STL内存池

结论:

包括;单独的标头不会导致内存泄漏,但由于 C 库的内存池管理,它可能会在 Valgrind 中触发仍然可达的警告。此行为是预期行为,而不是错误。禁用 STL 优化可以消除这些警告,但这可能会以性能下降为代价。

以上是为什么在 C 中包含 `` 会导致 Valgrind 的'Still Rereachable”警告?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn