2013-07-09 42 views
6

我正在嘗試使用malloc動態地創建大小爲2的數組。這裏是我的代碼:整數數組的動態內存分配

int *d = (int*)malloc(2 * sizeof(int)); 
d[0] = 4; 
d[1] = 5; 
d[2] = 8; 
d[3] = 9; 
d[4] = 7; 
int i; 

for (i = 0; i < 5; i++) 
    printf("%d \n", d[i]); 

當我運行此代碼時,它打印4, 5, 8, 9, 7

我想知道它是如何能夠分配更多的內存(5整數)比我請求(2整數)?

+1

您的代碼行爲是未定義意味着在不同的執行過程中您可能會注意到不同的行爲,您無法事先預測,您的程序可能會在某個時候崩潰。此代碼錯誤!不幸的是C編譯器不報告這一點。 –

回答

9

我想知道它是如何分配比我要求的更多的內存。

它沒有。您正在調用未定義的行爲。一個可能的結果*是您的程序似乎「工作」。


*可以說是最糟糕的。

3

就像奧利說的,它是undefined。它可能工作,可能不會。但現實情況是,即使它可能在99%的時間內工作,它至少也會失敗一次,並且你會得到一個SEGFAULT來讀或寫你的進程不應該使用的內存,而你最終還會導致幾乎不可調試的內存泄漏。

1

C不做邊界檢查。你正在跺腳你的程序不擁有的內存。

1

當你調用未定義的行爲時,你永遠不知道會發生什麼。例如,當我跑的程序,我得到了以下爲我的輸出:

4,5,8,51,1629501832

2

除了一直建議,如果我可以添加一些額外的注意事項。

不知道你正在運行這個操作系統,但如果你在Linux上任何時候你不確定是否應該工作或不運行valgrind。就我而言,它編譯了一個關於代碼中所有錯誤的良好報告(包括不釋放malloc -ed內存)。

我得到了三個Invalid write of size 4你對存儲器做了三個額外的寫操作。它也通知我,你是在環路與Invalid read of size 4讀取無效的內存,最後它給了我在你的代碼的泄漏,一些統計數據:

HEAP SUMMARY: 
    in use at exit: 8 bytes in 1 blocks 
    total heap usage: 1 allocs, 0 frees, 8 bytes allocated 

LEAK SUMMARY: 
    definitely lost: 8 bytes in 1 blocks 

最後,don't cast the result of malloc.

1

的原因,這似乎工作是因爲你正在增加你的指針來指向內存中的新點(你的程序可能被分配或不被分配使用)。我猜你是在堆棧中聲明的,這就是爲什麼你的未定義行爲看起來是「好的」。

我不認爲你明白指針的功能和你使用的語法。備註,以下是等價的:

int arr[ 2 ] = { 1, 2 }; 
int *pi = &arr; 

// The following output is equivalent to... 
for (int i = 0; i < 2; i++) { 
    printf("arr[i] = %d.\n", arr[ i ]); 
} 

// this. 
for (int i = 0; i < 2; i++) { 
    printf("*(p + i) = %d.\n", *(p + i)); 
} 

考慮這一點,替代實現你的代碼來強調你是如何通過你的陣列以外的索引元素指向新的內存地址。

int *d = (int *)malloc(2 * sizeof(int)); 

*(d + 0) = 4; // Observe you are accessing the memory location d points to. 
*(d + 1) = 5; // Observe you are accessing the memory location d + 4 bytes (or 8 if 64-bit) points to... 
*(d + 2) = 8; // ... 
*(d + 3) = 9; // ... 
*(d + 4) = 7; // Observe you are assigning a value to the memory location of d + 24 bytes (or 48 bytes if 64-bit). 

for (int i = 0; i < 5; i++) { 
    printf("%d \n", *(d + i)); 
} 

只是關於您的代碼的簡短說明。一個malloc通常應該跟隨一個免費的 - 所以適當使用它,所以沒有內存泄漏。

我希望這有助於!如果我犯了一個錯誤,請隨時糾正我。