【问题标题】:C++ program does nothing but Valgrind shows memory allocC++ 程序什么都不做,但 Valgrind 显示内存分配
【发布时间】:2020-09-27 07:35:16
【问题描述】:

当我发现一些奇怪的事情时,我正在玩弄 Valgrind: 我的 C++ 程序什么都不做,但是有 1 个内存分配和 1 个空闲。

我的简单程序:

int main() {
  return 0;
}

使用 g++ 编译并使用 Valgrind 检查时

> g++ main.cpp
> valgrind --leak-check=full --track-origins=yes ./a.out

==40790== Memcheck, a memory error detector
==40790== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==40790== Using Valgrind-3.16.0.GIT and LibVEX; rerun with -h for copyright info
==40790== Command: ./a.out
==40790== 
==40790== 
==40790== HEAP SUMMARY:
==40790==     in use at exit: 0 bytes in 0 blocks
==40790==   total heap usage: 1 allocs, 1 frees, 72,704 bytes allocated
==40790== 
==40790== All heap blocks were freed -- no leaks are possible
==40790== 
==40790== For lists of detected and suppressed errors, rerun with: -s
==40790== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

我的问题:我的程序什么都不做。 alloc 和 free 是从哪里来的?

有趣的是,使用 gcc 编译的同一程序显示零分配和释放:

> gcc main.c
> valgrind --leak-check=full --track-origins=yes ./a.out
==40740== Memcheck, a memory error detector
==40740== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==40740== Using Valgrind-3.16.0.GIT and LibVEX; rerun with -h for copyright info
==40740== Command: ./a.out
==40740== 
==40740== 
==40740== HEAP SUMMARY:
==40740==     in use at exit: 0 bytes in 0 blocks
==40740==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==40740== 
==40740== All heap blocks were freed -- no leaks are possible
==40740== 
==40740== For lists of detected and suppressed errors, rerun with: -s
==40740== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

后续问题:为什么同一段代码的两个内存分配不同?

编译器:gcc (GCC) 10.1.0
valgrind:valgrind-3.16.0.GIT

【问题讨论】:

  • C++ 库分配了一些东西供自己使用,然后将其删除。这里没有发生任何令人兴奋的事情。
  • 如果我没有链接或#include 任何东西,那会是什么?
  • 您肯定与某些东西相关联:标准 C++ 库。你的编译器为你做了。
  • @Donald 在 main 之前发生了很多事情,如果你好奇的话,可以使用gdb 之类的工具来看看是怎么回事 :)

标签: c++ gcc memory-leaks valgrind


【解决方案1】:

The main function 是代码的入口点。它不一定是(而且很少是)加载程序的操作系统进程的入口点。

在调用 main 函数之前,通常首先运行大量代码来设置标准库所需的内容(例如设置标准 I/O 流以及从操作系统获取实际参数)。

重要的是要注意main 函数的调用方式与任何其他函数一样。一旦它返回,它将返回初始化代码,该代码现在将自行清理(如释放它可能已分配的内存,并关闭流等)。

【讨论】:

  • 最后一段的第一句有点笨拙——main() 不像其他函数那样被调用。它只能从为程序设置的“大量代码”中调用,C++ 标准明确禁止从任何其他代码中调用它。是的,一些实现可能会像任何其他函数一样调用它(即,对于那些特定的实现,main() 像任何其他函数一样被调用)但 C++ 标准并不要求这样做。
猜你喜欢
  • 2021-06-29
  • 1970-01-01
  • 2021-12-25
  • 2017-10-31
  • 1970-01-01
  • 1970-01-01
  • 2011-07-19
  • 1970-01-01
  • 2022-11-30
相关资源
最近更新 更多