2013-05-06 151 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++;