web-dev-qa-db-ja.com

Cで構造体の2次元配列を実装する方法

私は現在、Cで構造体の2次元配列を実装する方法を理解しようとしています。私のコードは常にクラッシュしており、すべてのアプローチがC:ガベージに固執するようにコードを終了させようとしています。これは私が得たものです:

typedef struct {
    int i;
} test;

test* t[20][20];
*t = (test*) malloc(sizeof(test) * 20 * 20);

私の輝かしいエラー:

エラー:タイプ「structtest *」からタイプ「structtest * [20]」に割り当てるときに互換性のないタイプ

2次元ごとにメモリを個別に割り当てる必要がありますか?気が狂っている。とてもシンプルなはずです。いつの日か、タイムマシンを構築して、いくつかのc-compiler-floppiesを磁化します...

13
PenthousePauper

これで十分です:

typedef struct {
    int i;
} test;

test t[20][20];

これにより、サイズ20 x20のtestの2次元配列が宣言されます。mallocを使用する必要はありません。

配列を動的に割り当てたい場合は、次のようにすることができます。

// in a function of course
test **t = (test **)malloc(20 * sizeof(test *));
for (i = 0; i < 20; ++i)
    t[i] = (test *)malloc(20 * sizeof(test));
27
IVlad
test **t;

t = (test **)malloc(sizeof(test *) * 20);
for (i = 0; i < 20; i++) {
   t[i] = (test *)malloc(sizeof(test) * 20);
}
7
BobTurbo

他の回答はそれを修正する方法を示していますが、その理由は説明されていません。コンパイラが示唆しているように、元の例のtの型は実際にはtest *[20]であるため、test *へのキャストでは不十分でした。

Cでは、次元Nの配列Tの名前は、実際には*T[dim0][dim1]...[dimN-1]型です。楽しい。

3
msw

私の観察から、あなたはあなたが何を望んでいるかを正確に知らず、構造体とポインタの算術で混乱するかもしれません。次の2つの可能性を試してください。

1)各要素を持つ2次元配列には、testへのポインターがあります。この場合、testsへのすべてのポインタのメモリはすでに静的に割り当てられていますです。しかし、実際のtestsのメモリは準備ができていません。この場合、test [i][j]を1つずつ入力する必要があります。

testはメモリ内で個別であり、個別に動的に作成または破棄できるという利点があります。

typedef struct {
    int i;
} test;

test* t[20][20]; 
/* or instead of statically allocated the memory of all the pointers to tests
   you can do the following to dynamically allocate the memory
   test ***t;
   t = (test***)malloc(sizeof(test *) * 20 * 20);
*/ 

for (int i=0; i < 20; i++){
   for (int j=0; j < 20; j++){
      t[i][j] = malloc(sizeof(test));
   }
}

2)各要素を持つ2次元配列はtestです。この場合、すべてのtestsのメモリはすでに割り当て済みです。また、実際のtestsのメモリは、追加の準備なしで使用する準備ができています。

すべてのtestsは、大きなブロックとしてメモリ内で連続しており、常にそこにあります。これは、特定のピーク時にすべてのtestのみが必要であり、ほとんどの場合、それらの一部のみを使用する場合、メモリのチャンクを浪費する可能性があることを意味します。

typedef struct {
    int i;
} test;

test t[20][20]; 
/* or instead of statically allocated the memory of all tests
   you can do the following to dynamically allocate the memory
   test **t;
   t = (test**)malloc(sizeof(test) * 20 * 20);
*/ 
2
ttchong

また、内部ディメンションのサイズが一定である限り、その内部ディメンションのカウントを可変数割り当てることができます。

int n = ...;
test (*t)[20] = malloc(sizeof (*t) * n);
t[0 .. (n-1)][0 .. 19] = ...;