2012-02-10 59 views
3

我想malloc的一個巨大的四維陣列(192演出提供)下維數組;但是出現的內容與出現的內容不匹配(請參見下面的代碼中的assert())。 (我做了定義尺寸小,但真正的數字是:20,9000,195,120)C:多維數組使用蓋

#define SIZE_A 1 
#define SIZE_B 3 
#define SIZE_C 4 
#define SIZE_D 2 

#define offSet(a,b,c,d) (((size_t) SIZE_A * SIZE_B * SIZE_C * a) + ((size_t) SIZE_B * SIZE_C * b) + ((size_t) SIZE_C * c) + d) 

void xall(void) 
{ 
int *aray = (int *) malloc((size_t) SIZE_A * SIZE_B * SIZE_C * SIZE_D * sizeof(int)); 


int counter = 0; 

    for (int a = 0; a < SIZE_A; ++a){ 
     for (int b = 0; b < SIZE_B; ++b){ 
      for (int c = 0; c < SIZE_C; ++c) { 
       for (int d = 0; d < SIZE_D; ++d){ 
        aray[ offSet(a,b,c,d) ] = counter++; 

       }}}} 


counter = 0;  
    for (int a = 0; a < SIZE_A; ++a){ 
     for (int b = 0; b < SIZE_B; ++b){ 
      for (int c = 0; c < SIZE_C; ++c) { 
       for (int d = 0; d < SIZE_D; ++d){  
        int value = aray[ offSet(a,b,c,d) ] ; 
        assert(value == counter++); 

       }}}} 
} 

回答

1

您的宏是不太正確的。將其更改爲:

#define offSet(a,b,c,d) (((size_t) SIZE_B * SIZE_C * SIZE_D * a) + ((size_t) SIZE_C * SIZE_D * b) + ((size_t) SIZE_D * c) + d) 

您基本上已將您的SIZE_X移過1個字母。

我也建議把周圍的宏觀參數()

#define offSet(a,b,c,d) (((size_t) SIZE_B * SIZE_C * SIZE_D * (a)) + ((size_t) SIZE_C * SIZE_D * (b)) + ((size_t) SIZE_D * (c)) + (d)) 
0

我似乎宏應該是這樣定義的:

#define offSet(a,b,c,d) (((size_t) SIZE_B * SIZE_C *SIZE_D * a) + ((size_t) SIZE_C *SIZE_D * b) + ((size_t) SSIZE_D * c) + d) 
5

您的宏是錯誤的,因爲其他人提及。解決這個問題很好,但我建議你直接分配一個多維數組,而不是手動滾動偏移宏。看看這個例子:

#include <assert.h> 
#include <stdlib.h> 

#define SIZE_A 1 
#define SIZE_B 3 
#define SIZE_C 4 
#define SIZE_D 2 

int main(void) 
{ 
    int counter = 0; 
    int (*array)[SIZE_A][SIZE_B][SIZE_C][SIZE_D] = 
      malloc(sizeof(int) * SIZE_A * SIZE_B * SIZE_C * SIZE_D); 

    for (int a = 0; a < SIZE_A; ++a) 
    for (int b = 0; b < SIZE_B; ++b) 
     for (int c = 0; c < SIZE_C; ++c) 
     for (int d = 0; d < SIZE_D; ++d) 
      (*array)[a][b][c][d] = counter++; 

    counter = 0;  
    for (int a = 0; a < SIZE_A; ++a) 
    for (int b = 0; b < SIZE_B; ++b) 
     for (int c = 0; c < SIZE_C; ++c) 
     for (int d = 0; d < SIZE_D; ++d) 
     { 
      int value = (*array)[a][b][c][d]; 
      assert(value == counter++); 
     } 

    return 0; 
} 

在這個例子中分配數組的內存佈局,因爲它是你的問題完全一樣,但爲什麼不讓編譯器爲你做的工作?

對位的社論一邊的 - 不要投在C程序中調用malloc()的返回值。從void *轉換是隱式的,並且具有明確的轉換可以隱藏隱函數聲明警告,你會得到其他方式 - 例如,如果你忘了包括stdlib.h

+0

好一點,但問題是尺寸爲Visual C過大:該陣列的總大小超過4千兆字節,而我得到的有關數組大小的C2148錯誤太大。 – PaeneInsula 2012-02-10 22:58:43

+0

但你可以分配這麼多,並將其分配給一個簡單的指針?我不明白。 – 2012-02-10 23:01:26

+0

如果你的數組大於4GB,你應該把更多的內存放到你的計算機上並使用64位操作系統。 – mikithskegg 2012-02-10 23:03:09

0

在一些OS中,每個過程的存儲器分配的限制。通常默認值可能會改變。

別人,也不例如調用malloc時,如Linux甚至分配實際內存,你可能會試圖寫它時以後失敗了,但我想這不是你的情況。

嘗試檢查,如果你能控制的最大分配系統對每個進程的內存。 希望你找到答案,這確實很有趣。

一些閱讀的東西:

http://duartes.org/gustavo/blog/post/anatomy-of-a-program-in-memory http://www.linux-mag.com/id/827/