2014-01-11 41 views
1

我需要實現一個簡單的指向一個typedef指針的動態指針數組。
每次用戶請求時使用realloc,數組的大小將按sizeof(指針)增長。
所以我有是這樣的:在調用realloc之後,是否需要初始化(設置爲0)內存?

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
typedef void* node; 

void printmem(node* a, int c) { 
    int i; 
    for (i = 0; i < c; ++i) 
    { 
     printf("%d\t\t%p\n", i, a[i]); 
    } 
} 

int main(void) { 
    node* nodes = NULL; 
    int i = 0, count = 20; 

    for (i = 0; i < count; ++i) 
    { 
     nodes = realloc(nodes, sizeof(node)); 
    } 
    printf("Done reallocating\n"); 
    printmem(nodes, i); 
    // free(a); 
    return 0; 
} 

這給出了以下的輸出:

Done reallocating 
0  (nil) 
1  (nil) 
2  (nil) 
3  0x20fe1 
4  (nil) 
5  (nil) 
6  (nil) 
7  (nil) 
8  (nil) 
9  (nil) 
10  (nil) 
11  (nil) 
12  (nil) 
13  (nil) 
14  (nil) 
15  (nil) 
16  (nil) 
17  (nil) 
18  (nil) 
19  (nil) 

我所關心的第三元素,其含量。
這就是爲什麼我問是否應該在新的realloc後設置爲0的內存。

編輯:
所以,指出C的標準,由H2CO3,新的呼叫到realloc的,就是:
nodes = realloc(nodes, (i+1)*sizeof(node));
而在這之後的initiallization,我這樣做: nodes[i] = NULL
這也工作得很好。

EDIT2:
我現在有這樣的:

int main(void) { 
    node* nodes = NULL; 
    int i = 0, count = 20; 

    for (i = 0; i < count; ++i) 
    { 
     nodes = realloc(nodes, (i+1)*sizeof(node)); 
     nodes[i] = NULL; 
     if (i == 1) { 
      nodes[i] = &count; 
     } 
    } 
    printf("Done reallocating\n"); 
    printmem(nodes, i); 
    printf("\t*nodes[1] == %d\n", *(int*)nodes[1]); 
    printf("\tAddress of count is %p\n", &count); 
    // free(a); 
    return 0; 
} 
+1

'realloc()'將複製原先在緩衝區中的內容。如果新塊大於原始塊,則末尾的元素(即原始數組中未存在的元素)將被初始化。 – 2014-01-11 20:05:16

+0

@ H2CO3:新塊肯定比舊塊大,所有以前的數據都丟失了? – Chris

+0

Naw。再次閱讀我的評論。多餘的元素將被初始化,保存內存塊開始處的原始內容。 – 2014-01-11 20:16:40

回答

5

嗯,這要看情況。你要求內存初始化爲0?如果不是,那麼不,你不需要做任何事情。與malloc的情況一樣,realloc不執行任何初始化。原始塊中存在的任何內存都未初始化。

+0

所以我應該爲每次添加的特定新元素調用memset? – Chris

+0

好吧,再一次,這一切取決於是否需要您初始化此內存。如果是這樣,那麼是的。然而,重要的是要認識到C不能保證空指針由全零位表示,只是它將* *等於'0'。一個微妙但重要的區別。 –

1

去通過的realloc的定義()

realloc的(無效* P,爲size_t大小)改變對象的大小指出 由psize。內容將保持不變,直到舊的和新的尺寸的最小值。如果新尺寸較大,則新空間爲 未初始化。 (來自Kernighan和Ritchie)

您可能需要初始化新空間。你可以在確定void *所指向的地址是什麼類型的數據的時候這樣做。

2

請注意,空指針不必等於C中的立即數0,它只能保證不等於任何有效指針。另外,對於不同的指針類型(例如函數指針與char指針),技術上允許空指針是不同的。

因此,簡單地將內存初始化爲零可能會調用未定義的行爲。

所以初始化爲NULL,將是正確的!這就是我所做的!克里斯 -

不,你會做的就是投空這樣的:(無效*)NULL,寫這個內存位置。但是你從來沒有真正寫過你的malloc(通過傳遞NULL給realloc)。你基本上只是在你的printf中讀取未初始化的內存(這是未定義的行爲)。

+0

因此初始化爲NULL,將是正確的!這就是我所做的! – Chris

+0

你能解釋一下(void *)NULL和NULL之間的區別嗎?我已經使用了這兩個程序並運行了valgrind程序並沒有發生錯誤。另外,爲什麼我不寫信給我分配的記憶?我已經發布了main的更新,如果你運行它,你會看到nodes [1]輸出'c'變量的地址並且打印'*(nodes [i])'我得到'c '。 – Chris

+0

@Chris:如果在某些體系結構上,nullptr!= 0,那麼編譯器必須知道將適當的值放入內存中。它必須知道內存的引用位將被視爲一個指針。如果不同的指針類型具有不同的nullptr值,編譯器還必須知道它需要寫入內存的空指針的* type *類型。 – EOF

相關問題