Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mac上的C-Valgrind显示与linux不同的结果?_C_Linux_Macos_Valgrind - Fatal编程技术网

Mac上的C-Valgrind显示与linux不同的结果?

Mac上的C-Valgrind显示与linux不同的结果?,c,linux,macos,valgrind,C,Linux,Macos,Valgrind,下面是我编写的一个非常简单的程序,用于显示Mac(El Capitan)和Linux Mint 17.2上valgrind输出的差异 有没有办法在mac上获得相同类型的输出?我不明白为什么mac上的堆使用率比Linux上的要高 出于一个奇怪的原因,LinuxMint显示内存被释放,而OSX则没有 #include <stdio.h> #include <string.h> #include <stdlib.h> int main(int argc, char

下面是我编写的一个非常简单的程序,用于显示Mac(El Capitan)和Linux Mint 17.2上valgrind输出的差异

有没有办法在mac上获得相同类型的输出?我不明白为什么mac上的堆使用率比Linux上的要高

出于一个奇怪的原因,LinuxMint显示内存被释放,而OSX则没有

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char const *argv[]) {

  char *str = (char *)malloc(15);
  strcpy(str, "Hello World!");
  printf("%s\n", str);
  free(str);
  return 0;
}
#包括
#包括
#包括
int main(int argc,char const*argv[]{
char*str=(char*)malloc(15);
strcpy(str,“你好,世界!”);
printf(“%s\n”,str);
自由基(str);
返回0;
}
Linux Mint 17.2

Mac OSX El Capitan

在调用
main
之前,C标准库和运行时会执行一些操作,
printf
也会在内部执行这些操作。这些“东西”可能包括内存分配。这是特定于实现的,因此完全不同的实现显示不同的分配量也就不足为奇了

然后,当程序退出时,实际上可能不需要
释放
任何堆分配,因为当进程终止时,堆将消失,poof,被操作系统删除(在像上面两个一样的桌面操作系统中)。应用程序代码应该释放它分配的所有内存(因为可移植性,因为这样你就可以实际使用像valgrind这样的工具,因为它是“干净的”)。但对于特定于平台和编译器的库代码,它只会减慢每个程序的退出速度,而不会带来任何好处。所以库不这样做基本上是一种优化,通常不应该在您自己的程序中这样做(除非您可以实际测量它在某个地方产生的影响)

所以像valgrind这样的工具通常包含已知未释放内存块的抑制列表。您还可以为您使用的任何库配置自己的抑制列表,这些库不会在程序退出时释放所有内存。但在使用抑制时,最好确保您正在抑制安全案例,而不是隐藏实际的内存泄漏



推测:因为这里的分配数量差异很大,有人可能会猜测Linux实现只使用静态/全局变量,而Mac实现也使用堆分配。存储在那里的实际数据可能包括stdin/stdout/stderr缓冲区之类的东西。现在这只是一个猜测,我没有检查源代码,但目的是让您了解可能需要分配什么。

您需要学习如何解释结果,尤其是在Mac OS X上

你的Mac输出显示(我希望我不必输入这个-该死,屏幕图像太痛苦了!):

也就是说,你没有内存泄漏。被抑制的内容来自macc运行库启动代码。它分配了相当多的空间(您机器上的大部分空间为26kib,有184个单独的分配),并且在程序执行之前不会显式释放空间。这就是为什么它们被压制的原因——它们不是你程序的错误,你对此基本上无能为力。这就是Mac上的生活方式。FWIW,我刚刚运行了一个程序,得到:

==57081== 
==57081== HEAP SUMMARY:
==57081==     in use at exit: 38,858 bytes in 419 blocks
==57081==   total heap usage: 550 allocs, 131 frees, 46,314 bytes allocated
==57081== 
==57081== LEAK SUMMARY:
==57081==    definitely lost: 0 bytes in 0 blocks
==57081==    indirectly lost: 0 bytes in 0 blocks
==57081==      possibly lost: 0 bytes in 0 blocks
==57081==    still reachable: 0 bytes in 0 blocks
==57081==         suppressed: 38,858 bytes in 419 blocks
==57081== 
==57081== For counts of detected and suppressed errors, rerun with: -v
==57081== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
我不知道为什么我的运行时系统比您多12 KiB的空间和235个分配。然而,这绝对是Mac上的正常行为


如果对o/s进行重大升级,旧的抑制可能会停止有效,您可能会突然遇到更多的“仍然可以访问”或其他内存“问题”;此时,您将仔细检查报告,然后生成新的抑制。我有一个文件,其中有84个抑制项,我曾经使用过,然后我得到了一个新版本的Valgrind,它们已经存在。

因为它是一个新版本?@MikeCAT-为什么会有不同?我的问题是,它没有显示或说内存正在释放(所有堆都已释放)。环境可能会从堆中为内部结构分配一些块(例如stdio句柄或类似的)。不释放它们是可以的,因为它们在进程终止时被操作系统自动回收。这不被视为内存泄漏。泄漏会随着时间的推移而增加。我猜OS X上的启动代码(在
main
之前运行的东西)正在分配
main
返回后未释放的数据,因为它在进程终止时是自由的。valgrind检测到这些“丢失的”空闲,但显然知道它们不是问题(显示0个错误)@DanielJour-是否可以进行配置,以便以不同的方式显示?
==57081== 
==57081== HEAP SUMMARY:
==57081==     in use at exit: 38,858 bytes in 419 blocks
==57081==   total heap usage: 550 allocs, 131 frees, 46,314 bytes allocated
==57081== 
==57081== LEAK SUMMARY:
==57081==    definitely lost: 0 bytes in 0 blocks
==57081==    indirectly lost: 0 bytes in 0 blocks
==57081==      possibly lost: 0 bytes in 0 blocks
==57081==    still reachable: 0 bytes in 0 blocks
==57081==         suppressed: 38,858 bytes in 419 blocks
==57081== 
==57081== For counts of detected and suppressed errors, rerun with: -v
==57081== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)