2014-07-21 92 views
0

用C創建二維數組很簡單:如何在C中分配3維數組?

char (*arr)[50] = malloc(sizeof(arr) * 10 * 50); // 10x50 matrix 

你怎麼做用C三維數組?它看起來並不像我可以這樣做:

char (**arr)[50] = malloc(sizeof(arr) * 10 * 20 * 50); // 10x20x50 matrix? 
+1

'sizeof(char)* 10 * 50'將是一個10x50的字符矩陣,不是? –

+0

@RickyMutschlechner會的。 :)但它是一個2-dim矩陣。但我不知道如何做3-dim ... – bodacydo

+0

@RudyVelthuis這與編寫sizeof(char)相同。 (編輯:我認爲) – bodacydo

回答

3

三維陣列需要2個維度被稱爲

char (*arr)[20][50] = malloc(sizeof(char) * 10 * 20 * 50) 

注:我已經糾正的sizeof(ARR)爲sizeof(炭),因爲sizeof(arr)將返回指針的大小。

+2

'sizeof(char)'總是多餘的...... – Deduplicator

+0

是的,我同意。我傾向於這樣做,以便於識別分配的類型。或者更好的辦法是說malloc(sizeof(char [10] [20] [30]))。 – user1969104

+1

在這種情況下,你做錯了。 'sizeof *** arr'是有道理的,但最好的情況* *文檔*變得陳舊和*不*錯誤。 – Deduplicator

0
char (*arr)[20][50] = malloc(sizeof(char) * 10 * 20 * 50); 

sizeof(char)保證是1.因此,它可以省略。

char (*arr)[20][50] = malloc(10 * 20 * 50); 
1

一種可能的方式可能是分配單維數組,

int width=10; length=20; height=50; 
char* arr = malloc(width*length*height); 
if (!arr) { perror("malloc"); exit(EXIT_FAILURE); }; 

然後有一些方法來訪問它,例如宏

#define Element(I,J,K) arr[width*length*(I)+length*(J)+(K)] 

,並使用Element(i,j,k)

你可以打包這一切使用flexible array member

struct my3dstring_st { 
    int width; 
    int length; 
    int height; 
    char arr[]; 
}; 

然後有ag一個決策函數

struct my3dstring_st * 
    make_my3dstring (int width, int length, int height) 
    { 
    if (width<=0 || length<=0 || height<=0) return NULL; 
    struct my3dstring_st* s = 
     malloc(sizeof(struct my3dstring_st) 
       + width * length * height); 
    if (!s) {perror("malloc"); exit(EXIT_FAILURE); }; 
    s->width = width; 
    s->length = length; 
    s->height = height; 
    memset (s->arr, 0, width * length * height); 
    return s; 
    } 

和在線訪問功能(在頭文件):

static inline int 
    access_m3dstring(struct my3dstring_st*s, int i, int j, int k) { 
    if (!s || i<0 || j<0 || k<0 
     || i>=s->width || j>=s->height || k>=s->length) return EOF; 
    return s->arr[i*->width*s->height + j*s->height + k]; 
    } 

我留下作爲一個練習寫的修改功能modify_m3dstring,你可能有不安全的,但更快的變體不做任何檢查...

+0

謝謝,這非常酷!修改函數可以像'Element [i,j,k] = x;':)一樣簡單 – bodacydo

+0

如果您想要修改某些'struct my3dstring_st *'指針作爲參數傳遞,則不會。我的宏'元素'只適用於'arr'是* global *變量(或形式參數但很醜)。 –

+0

static-inline int access_m3dstring(struct my3dstring_st * s,int i,int j,int k,char val){if {|| || || <0 || j <0 || k <0 || i > = s-> width || j> = s-> height || k> = s-> length)return EOF; s-> arr [i * - > width * s-> height + j * s-> height + k] = val; }' – bodacydo

1

一般規則:

T *arr   = malloc(sizeof *arr * n); // for an N-element array 
T (*arr)[N] = malloc(sizeof *arr * m); // for an NxM-element array 
T (*arr)[N][M] = malloc(sizeof *arr * k); // for an NxMxK-element array 

其中大寫字母表示編譯時已知的值,小寫字母表示運行時已知的值。高維數組的模式應該很明顯。

如果使用C99編譯器或支持可變長度數組一個C2011編譯器,則可以使用運行時變量爲所有的尺寸:

size_t n = some_value(); 
size_t m = some_other_value(); 
size_t k = yet_another_value(); 

T (*arr)[n][m] = malloc(sizeof *arr * k); 

類型表達*arrT [n][m],所以sizeof *arr給出與sizeof (T) * n * m相同的結果;結果更容易閱讀並且不易出錯。

如果你的編譯器不支持沃拉斯,你不知道在編譯時你的尺寸,你要麼必須分配爲1-d陣列和手動計算偏移:

T *arr = malloc(sizeof *arr * n * m * k); 
... 
arr[ 3*n*m + 2*m + 1] = x; // equivalient to arr[3][2][1] = x 

或者,如果你能不被記憶相鄰的行活,你可以改小分配數組:

T ***arr = malloc (sizeof *arr * n); 
for (size_t i = 0; i < n; i++) 
{ 
    arr[i] = malloc(sizeof *arr[i] * m); 
    for (size_t j = 0; j < m; j++) 
    { 
    arr[i][j] = malloc(sizeof *arr[i][j] * k) 
    } 
} 

理想情況下,你應該檢查每個malloc的結果,以確保它成功了。你必須按照你分配的順序釋放數組: