2013-03-08 138 views
6

我處於項目的中間,我試圖使用malloc()realloc()。我知道當我使用malloc時,它可以工作,但是當我使用realloc時,它根本不會改變已分配內存的數量。我一直認爲realloc會重新分配你已經配對的內存。內存不重新分配

以下是我有:

這包括:

#include <stdlib.h> 

我有一個結構:

struct student { 
    int age; 
    int numOfClasses; 
    int gender; //0 male; 1 female 
} student; 

當我想用malloc使這些結構的7,我會使用此行代碼:

student stud* = (structure*) malloc(7*sizeof(student)); 

此行可行。該代碼行採用結構的大小和7倍數。總之,這將獲取足夠的內存來創建7個結構的數組。現在

,如果我想改變這種狀況到8,我會做到這一點,其中A是以前的malloc內存,並且B是新malloced(或realloced)內存:

enter image description here

這裏我如何在代碼中:

stud = (student*)realloc(stud, 8*sizeof(student)); 

從我所知道的,realloc在第二個參數和mallocs中獲取該變量的內存量。然後,它需要指針(或先前的malloced),並儘可能地從給定的指針中填充剛纔的malloced內存。當然,第二個參數必須大於以前的malloced大小,否則stud會在最後失去一些內存。現在這是我的問題所在。當我打電話給上面的行時,它不會改變任何東西。 malloced數組仍然是7的長度。我也很確定,我有足夠的內存來重新分配。

我正在做這個對嗎?我的問題在哪裏?

+8

是什麼讓你認爲malloced數組的長度仍然是7? – 2013-03-08 13:02:37

+0

這與你的問題沒有關係,但我認爲你的結構對於'enum'完全有用。 – teppic 2013-03-08 13:16:16

回答

11

您對realloc的行爲的理解幾乎是正確的。它不會返回一個不同的指針;可能是因爲在初始塊之後有足夠的未使用的內存,所以堆管理器可以將相同的指針返回給你(但是調整它自己的內部狀態以便它知道塊現在更大)。

雖然你犯了一個小錯誤。

stud = (student*)realloc(stud, 8*sizeof(student)); 

在這裏,您是從realloc的返回值替換您的stud指針。如果由於內存不足而返回NULL,那麼指針已經丟失,原來的stud指針出現泄漏。您應該使用臨時指針。

tmp = realloc(stud, 8*sizeof(student)); 
if (tmp) 
    stud = tmp; 

另外請注意,您仍然必須在第八個插槽中放置一些東西。 realloc之後,第八個插槽是有效分配的內存,但包含垃圾,直到您存儲了有意義的內容爲止。

+0

我很確定有足夠的內存來重新分配。 – 2013-03-08 13:22:37

+1

好的,但你仍然沒有解釋爲什麼你認爲malloced數組仍然是長度爲7. – 2013-03-08 13:23:35

+0

這是事情,我不知道爲什麼它不是從7分配到8。 – 2013-03-08 13:37:18

4

這應該工作,雖然我有以下建議:

不要投通過malloc回報。在C中沒用,可能會隱藏,忘記包含<stdlib.h>

請勿使用ptr = realloc (ptr, ...),因爲這會在realloc返回NULL的情況下創建內存泄漏。相反,使用

if ((new_ptr = realloc (stud, 8 * sizeof (*stud))) != NULL) { 
    stud = new_ptr; 
} else { 
    scream_and_die("out of memory"); 
} 

並使用sizeof (*stud),即參考使用指針,而不是類型被指向到的表達式(要獨立你分配的特定類型的指針的)。這樣,當您重命名typedef時,malloc/realloc行不需要修改。換句話說,C中動態內存分配的最佳實踐是

#include <stdlib.h> 
sometype *ptr; 
... 
ptr = malloc (N * sizeof *ptr); 

對於N個類型的數組。