2012-10-01 23 views
24

我學習如何在C.創建動態1D陣列下面的代碼試圖做到這一點:C中的動態數組 - 我對malloc/realloc的理解是否正確?

  1. 創建長度10的動態數組中,保持雙打,使用 的malloc。
  2. 對於j = 0,1,...,9,將數組的每個條目設置爲j/100。然後打印 它出來。
  3. 使用realloc在數組的末尾添加一個額外的空條目。
  4. 將新條目設置爲j/100並再次打印每個條目。

測試

double* data = (double*)malloc(10*sizeof(double)); 

for (j=0;j<10;j++) 
{ 
     data[j]= ((double)j)/100; 
     printf("%g, ",data[j]); 
} 

printf("\n"); 

data = (double*)realloc(data,11*sizeof(double)); 

for (j=0;j<11;j++) 
{ 
    if (j == 10){ data[j]= ((double)j)/100; } 
    printf("%g, ",data[j]); 
} 

free((void*) data); 

問題

1)我是不是編碼這個權利?

2)教程我發現使用malloc沒有把(double*)放在前面。例如。

int *pointer; 

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

這並不編譯我在Visual Studio 2010中,Windows 7的錯誤是「void類型的值不能被分配到int類型的實體」。

爲什麼它適用於那些教程而不適合我?我猜對了,這是因爲他們使用的編譯器在我的例子中自動填入(int*)

+0

「void類型的值不能分配給int類型的實體」不是* C *編譯器應該產生的錯誤。問題是你正在使用* C++編譯器*。確保您的源文件名爲' .c'。 –

回答

31

你很近。

在C(自1989年版的標準中的至少)mallocrealloc之前投是不必要的,因爲C可void *類型的值轉換爲int *沒有石膏。這是而不是對於C++是正確的,所以根據你得到的錯誤,這聽起來像你正在編譯的代碼是C++而不是C。檢查VS2010的文檔以確定如何將代碼編譯爲C.

以下是我的用於寫入malloc呼叫優選式:

double *data = malloc(10 * sizeof *data); 

由於表達*data的類型是doublesizeof *data相當於sizeof (double)。這也意味着如果data的類型發生變化,您不必調整malloc的呼叫。

至於realloc調用,將結果分配給臨時指針值更安全。 realloc將返回NULL,如果它不能擴展緩衝,所以它的安全寫

double *tmp; 
... 
tmp = realloc(data, 11 * sizeof *data); 
if (!tmp) 
{ 
    // could not resize data; handle as appropriate 
} 
else 
{ 
    data = tmp; 
    // process extended buffer 
} 

要知道,微軟的支持C與1989年版本的語言的結束;自那時以來,對語言標準進行了兩次修訂,其中引入了一些新功能並且棄用了舊功能。因此,雖然一些C編譯器支持C99功能,如混合聲明和代碼,可變長度數組等,VS2010不會。

+0

謝謝,這非常有幫助。 – Legendre

+0

更新:VS2015支持C99 +部分C11和WinXP目標選項。所以微軟在2015年繼續提供ISO C支持。 –

4

在C中,您不應該輸入malloc()的返回值。

此外,在malloc()參數中對類型進行編碼是一個壞主意。這是一個更好的辦法:

double* data = malloc(10 * sizeof *data); 
+1

編譯。但Visual Studio 2010警告說:「void類型的值不能用於初始化double類型的實體」。可以忽略警告嗎? – Legendre

10

1)我是不是編碼這個權利?

大部分。但如果realloc失敗,data = (double*)realloc(data,11*sizeof(double));會丟失對分配內存的引用,您應該使用臨時指針來保存返回值realloc並檢查它是否爲NULL(並且您還應該檢查返回值malloc)。

2)教程我發現在沒有把(double *)放在前面的情況下使用malloc。

在C中,malloc返回void*可以隱式地被轉換爲任何其它類型的指針,所以不需要流延(和廣泛泄氣因爲鑄造,可以隱藏錯誤)。 Visual Studio顯然將代碼編譯爲需要強制轉換的C++。

+0

+1感謝您的幫助。 – Legendre