17

私は次の構造体を持っています:

typedef struct _chess {
   int **array;
   int size;
   struct _chess *parent;
} chess;

そして、私が持っています:

typedef struct _chess *Chess;

ここで、チェス構造体へのポインターを格納する動的な長さの配列を作成したいので、次のようにします。

Chess array [] = malloc(size * sizeof(Chess));

これによりエラーが発生します: 無効な初期化子です。

そして、[] をドロップしてこれを行うと:

Chess array = malloc(size * sizeof(Chess));

エラーなしでコンパイルされますが、次のようにしてこの配列の要素を NULL に設定しようとすると:

array[i]=NULL;

エラーが表示されます: 型 'void *' から型 'struct _chess' に代入するときに互換性のない型です</p>

私は何が間違っているのですか?ありがとう。

4

4 に答える 4

48

array少し誤解を招く名前です。動的に割り当てられたポインタの配列の場合、mallocはメモリのブロックへのポインタを返します。配列へのポインタを保持するのChess*ではなく、を使用する必要があります。Chess[]

Chess *array = malloc(size * sizeof(Chess));
array[i] = NULL;

そしておそらく後で:

/* create new struct chess */
array[i] = malloc(sizeof(struct chess));

/* set up its members */
array[i]->size = 0;
/* etc. */
于 2012-05-30T07:07:56.923 に答える
23

ここでは多くのtypedefことが起こっています。個人的には、「アスタリスクを隠す」ことに反対しています。つまり、typedefポインタ型をポインタのように見えないものに変換することです。C では、ポインターは非常に重要であり、実際にコードに影響を与えます。 と の間には多くの違いがfooありfoo *ます。

答えの多くもこれについて混乱していると思います。

Chess型の値へのポインターである値の配列の割り当てchess(これもまた、私が本当にお勧めできない非常に紛らわしい命名法です) は、次のようにする必要があります。

Chess *array = malloc(n * sizeof *array);

次に、ループして実際のインスタンスを初期化する必要があります。

for(i = 0; i < n; ++i)
  array[i] = NULL;

これは、インスタンスにメモリを割り当てたくないことを前提としています。最初は何も指していないすべてのポインターを持つポインターの配列が必要なだけです。

スペースを割り当てたい場合、最も単純な形式は次のようになります。

for(i = 0; i < n; ++i)
  array[i] = malloc(sizeof *array[i]);

使用法sizeofが 100% 一貫しており、明示的な型について言及し始めていないことを確認してください。変数に固有の型情報を使用し、コンパイラにどの型がどれであるかを心配させます。繰り返さないでください。

もちろん、上記はmalloc();に対して不必要に大量の呼び出しを行います。使用パターンによっては、malloc()必要な合計サイズを計算した後、 を 1 回呼び出すだけで上記のすべてを実行できる場合があります。array[i]その後、もちろん、大きなブロックを指すようにポインターを調べて初期化する必要があります。

于 2012-05-30T07:20:13.153 に答える
1

私見、これは良く見えます:

Chess *array = malloc(size * sizeof(Chess)); // array of pointers of size `size`

for ( int i =0; i < SOME_VALUE; ++i )
{
    array[i] = (Chess) malloc(sizeof(Chess));
}
于 2012-05-30T07:09:19.970 に答える