2013-05-06 121 views
1

在我的大学里,我们被要求创建一个分配所有可用内存的程序。 所以我认为制作一个无限循环和分配内存而不释放它必须消耗计算机的所有可用内存。 但是由于我没有释放内存,所以必须有大量的内存泄漏。无内存泄漏

所以我写了一个简单的程序,但是当我用valgrind检查它时,没有内存泄漏。没有任何。没有直接的间接泄漏。

请告诉我为什么。下面是我的程序:

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

int main() 
{ 
    int i,kb=0,mb=0; 
    char *some; 
    while(1) { 
     for(i=0;i<1024;i++) 
     { 
      // Allocating memory one kilobyte a time. 
      some = (char*) malloc(1024); 
      if(some == NULL) 
      { 
       exit(EXIT_FAILURE); 
      } 
      kb++; 
     } 
     // Displaying no. of mbs that have been allocated at each mb 
     mb++; 
     printf("%d mb\n",mb); 
    } 
    return 0; 
} 
+1

也许是因为编译器计算出该内存从'返回malloc'永远不会被使用,因此只需跳过编译该代码段? – Cyclonecode 2013-05-06 15:26:14

+0

我投了+1,因为我认为这是一个有趣的问题,我真的很想知道答案=) – Cyclonecode 2013-05-07 17:03:56

+0

您正在使用哪种编译器? – Cyclonecode 2013-05-09 04:37:20

回答

0

更换some = (char*) malloc(1024);这一点:some = new char[1024]; 它将在2000MB,如果你至少有那么多的空闲内存失败。但是,如果您在Win32环境中运行此操作,这将不会分配计算机中的所有可用内存,因为每个进程都有2GB的限制,所以在这种情况下,您需要另一种方法。

+0

为什么这种行为会有所不同?无论如何,这是C代码,所以'new'将不起作用。 – siride 2013-05-06 20:37:34

+0

你说得对,它不会在C中工作,对此抱歉。我在C++中尝试了它,并且抛出了一个新的异常,但不是使用malloc。这就是为什么我认为它可以帮助你。 – zoty314 2013-05-06 21:10:37

0

首先想到的是分配已经被优化掉 - 通常是完全分配或者推送到堆栈存储。在这种情况下,完全删除它会更好。

您通常通过阅读生成的程序集来证明或反驳此问题。

当我运行它
+0

我不擅长编程。我正在学。你的第一条线是有道理的。但我不明白你的第二行。你能帮我多些吗? – Ishan 2013-05-13 19:31:25

+0

@Ishan你的编译器可以为你输出汇编代码。这基本上是您配置的源代码(程序)(例如,使用优化设置)并转换为机器指令。学习阅读汇编代码需要一些时间,所以如果你以前从未做过,这可能不是最好的选择。我一直在做这10年;我还在学习:) – justin 2013-05-13 22:43:18

0

- Valgrind的认定问题:

==3335== 
==3335== HEAP SUMMARY: 
==3335==  in use at exit: 2,271,338,496 bytes in 2,218,104 blocks 
==3335== total heap usage: 2,218,105 allocs, 0 frees, 2,271,338,496 bytes allocated 
==3335== 
==3335== 
==3335==  Valgrind's memory management: out of memory: 
==3335==  newSuperblock's request for 8876032 bytes failed. 
==3335==  3116339200 bytes have already been allocated. 
==3335==  Valgrind cannot continue. Sorry. 
==3335== 
==3335==  There are several possible reasons for this. 
==3335==  - You have some kind of memory limit in place. Look at the 
==3335==  output of 'ulimit -a'. Is there a limit on the size of 
==3335==  virtual memory or address space? 
==3335==  - You have run out of swap space.` 

即使使用O2 O3不会删除错误。这是一个完整的样本吗?

UPD

标志没有改变输出,但如果我在飞机坠毁前中断程序,Valgrind的旁边会显示:

^C1890 mb 
==3286== 
==3286== HEAP SUMMARY: 
==3286==  in use at exit: 1,981,808,640 bytes in 1,935,360 blocks 
==3286== total heap usage: 1,935,360 allocs, 0 frees, 1,981,808,640 bytes allocated 
==3286== 
==3286== 276,480 bytes in 270 blocks are possibly lost in loss record 2 of 3 
==3286== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==3286== by 0x8048472: main (mem_test.c:13) 
==3286== 
==3286== 1,981,530,112 bytes in 1,935,088 blocks are definitely lost in loss record 3 of 3 
==3286== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==3286== by 0x8048472: main (mem_test.c:13) 
==3286== 
==3286== LEAK SUMMARY: 
==3286== definitely lost: 1,981,530,112 bytes in 1,935,088 blocks 
==3286== indirectly lost: 0 bytes in 0 blocks 
==3286==  possibly lost: 276,480 bytes in 270 blocks 
==3286== still reachable: 2,048 bytes in 2 blocks 
==3286==   suppressed: 0 bytes in 0 blocks 
==3286== Reachable blocks (those to which a pointer was found) are not shown. 
==3286== To see them, rerun with: --leak-check=full --show-reachable=yes 
==3286== 
==3286== For counts of detected and suppressed errors, rerun with: -v 
==3286== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0) 
+0

嘿,你可以显示valgrind运行时的结果--leak-check = full – Ishan 2013-05-13 19:32:49

+0

@Ishan标志本身不会改变输出 – ShPavel 2013-05-14 08:25:44

0

在Linux下,内核不限制的拨款,但有效利用的记忆。 (见https://www.kernel.org/doc/Documentation/vm/overcommit-accounting

$ echo 2 > /proc/sys/vm/overcommit_memory 

如果禁用此功能,否则按照预期的代码应该运行,如果你垫分配内存以0:

some = (char*) malloc(1024); 
if(some == NULL) { 
    exit(EXIT_FAILURE); 
} 
memset(some, 0, 1024); 
kb++;