2012-11-03 71 views
0

所有不尋常的初始化麻煩

我寫的動態二維數組聲明的一個非常簡單的C代碼,並與memset初始化,然後打印出值。我的代碼的東西如下:

float **env; 
int i,j,num; 

printf("Enter a number : \n"); 
scanf("%d",&num); 

env = (float **)malloc(num*sizeof(float *)); 

for(i=0;i<num;i++) 
{env[i] = (float *)malloc(num*sizeof(float));} 

memset(env, 0, sizeof(float)*num*num); 

for(i=0;i<num;i++) 
{ for (j=0;j<num;j++) 
    { 
     printf("%f\t",env[i][j]); 
     if (j == num -1) 
     { printf("\n\n");} 
    } 
} 

for(i=0;i<num;i++) 
{free(env[i]); 
} 

free(env); 

當我編譯程序,沒有編譯錯誤或警告,但是當我嘗試打印出來的值,我無法打印。然後我調試的程序,和ENV 2D可變正顯示出類似 CXX0030: Error: expression cannot be evaluatedmemset語句後,當我打印值會出現一個窗口,顯示

Unhandled exception at 0x008b1e27 in ***.exe: 0xC0000005: Access violation reading location 0x00000000.

我試圖明確地初始化二維數組ENV爲0使用2 for循環,它可以很好地工作,我也可以打印這些值,但是當我使用memset時它不起作用。如果有人能幫助我,那將會非常有幫助。謝謝。

回答

3

首先,通常的建議:停止使用sizeof下的類型名稱並停止投射malloc的結果。這是它應該已經看起來像

env = malloc(num * sizeof *env); 

for (i = 0; i < num; i++) 
    env[i] = malloc(num * sizeof *env[i]); 

一般情況下,更願意通過以下其次這種模式

some_ptr = malloc(N * sizeof *some_ptr); 

寫你的內存分配,在「陣列」通過使用這種技術建立不一個經典的C型連續2D陣列。相反,你會從一堆完全不相關的一維數組中組裝一個「模擬」二維數組。後者可能會隨機散佈在記憶中。這立即意味着您將無法將您的數組作爲連續對象處理。同時你的memset呼叫試圖做到這一點。你不能這樣做。在你的情況下,你必須獨立地使用一個循環來清零每個1D子陣列。

然而,代替獨立地分配的1D子陣列,則可以對其進行分配所有爲單個存儲器塊

assert(num > 0); 
env = malloc(num * sizeof *env); 
env[0] = malloc(num * num * sizeof *env[0]); 

for (i = 1; i < num; ++i) 
    env[i] = env[i - 1] + num; 

如果分配如上所示,則數組的數據將被存儲在單個連續存儲器塊,儘管你仍然需要了解你在使用這個數組的時候正在做什麼。例如,荷蘭國際集團memset陣列數據將如下所示

memset(*env, 0, num * num * sizeof **env); 

memset(&env[0][0], 0, num * num * sizeof env[0][0]); 

(這是相同的東西)。

+0

感謝您的意見,我包括你在我的代碼中提到的。所以考慮你所提到的,是否有任何方法將2D數組初始化爲0而不明確使用2 for循環? – duttasankha

+1

@duttasankha:查看我答案的第二部分。你的代碼是不可能的。但是如果你改變我的答案中所示的分配方案,它將成爲可能。 – AnT

+0

感謝您的幫助。但是,當我停止鑄造malloc然後我編譯器扔我錯誤像 錯誤:類型「void *」的值不能分配給類型「浮動**」的實體 錯誤:值類型「void *「不能分配給」float *「類型的實體 我該怎麼做才能做到這一點。我正在使用Microsoft Visual Studio 2010 – duttasankha

2

刪除memset並使用calloc而不是malloc,它將分配的內存零初始化。你現在正在做的是調零你剛分配的指針。

+0

如果我刪除了memset,那麼我將如何初始化二維數組? – duttasankha

+1

再次閱讀,calloc零初始化分配的內存 –

2

除了Michael的回答,重要的是要認識到float **env而不是給你一個連續的內存塊。它會給你一個指向連續內存塊的指針,並且在每個內存位置都有一個指向連續內存塊的指針,但不能保證這些塊是對齊的。

例如做:

int *x = malloc(sizeof(int)); 
int *y = malloc(sizeof(int)); 

x和y不能保證在內存中連續的,然而,這是你的代碼是假設。