3

ポインタの 2D 配列の動的メモリ割り当てと削除に非常に混乱しています。

目標は、各セルがリンクされたリストへのポインターを持つ 2D 配列を持つことです。これは私がやっていることであり、エラーは表示されませんが、警告はほとんどありません。

警告:

1)

a value of type queue ** cannot be used to initialize an entity of type queue ***
queue* (**table) = (queue**)malloc(sizeof(queue*)*3);

2)

a value of type queue * cannot be assigned to an entity of type queue **
    table[indexI] = (queue*)malloc(sizeof(queue*)*3);

3)

a value of type queue ** cannot be assigned to an entity of type queue ***
  if( !(table = allocate()) ) {

コードは次のとおりです。

queue **allocate() {

    queue* (**table) = (queue**)malloc(sizeof(queue*)*3);
    // Warning #1 at above line 
    for(.....) {

    table[index] = (queue*)malloc(sizeof(queue*)*3);
    // Warning #2 at above line. 
    }

    for(I index - 0 to 3) {
    for(J index - 0 to 3) {

    table[I][J] = NULL;

    }
    }
    return((queue**)table);
   }

    void deallocate(queue* **table) {


    // will handle list deletion
    // next deallocate table

    for(....) {
    free(table[index]);
    }
    free(table);

   }

void
add_list_to_queue(queue ***table) {

// here I create a list of queue type and assign it to
// those cells

}

modify_table() {

    queue* (**table) = NULL;

    table = allocate();
// Warning #3 at above line
.
.
.
    add_list_to_queue(table);

// do de allocation of table, list etc.,

    deallocate(table);

}

私はこれらの分野で混乱しています

  1. ポインターの 2D 配列の宣言が正しいかどうかわかりません
  2. この 2D 配列のポインターを渡すにはどうすればよいですか
4

2 に答える 2

2

最初の警告は、括弧が式の LHS に違いを生じさせないためです。

queue* (**table) = (queue**)malloc(sizeof(queue*)*3);

tableキューへの単純な 3 レベルのポインターです。ただしmalloc、キューへの 3 つのポインターを保持できるメモリ ブロックへのポインターを返すため、2 レベルのポインターをキューに割り当てています。

tableは 3 レベルのポインターであるため、table[indexI]は 2 レベルのポインターです。しかし、式の右辺に一貫性がありません:

table[indexI] = (queue*)malloc(sizeof(queue*)*3);

mallocキューへの 3 つのポインターを保持できるメモリ ブロックへのポインターを再び返します (つまり、malloc2 レベルのポインターを返します) が、それを 1 レベルのポインターとしてキャストしてから、2 レベルのポインターに割り当てます。 .

3 番目の警告についてはallocate()、キューへのポインターへのポインターを返すように定義しましたが、それを に割り当てようとしていますtable。上で説明したように、tableは 3 レベルのポインターですがallocate()、2 レベルのポインターのみを返します。

しかし実際には、複数レベルのポインター間接化は、ここで必要なものではありません。複雑にしないでおく。何必要ですか?行へのポインター。各行にはキューへのポインターが含まれます。それが、彼のコメントでの H2CO3 の提案です。

queue *(*arr)[COLUMNS] = malloc(sizeof(*arr) * ROWS);

arrは、ROWS の配列へのポインタであり、各行には への COLUMNS ポインタが含まれていqueueます。

編集:コメントで尋ねたように、これをさまざまな関数に渡すには、最初にポインターを宣言して初期化します。

queue* (*arr) [COLUMNS] = NULL;

次に、メモリを割り当てるには、ポインタが指すものを変更する必要があることに注意してください。したがって、ポインターにポインターを渡す必要があります。関数プロトタイプは次のようにする必要があります。

void allocate (queue* (**arr) [COLUMNS]);  // Note the (**arr)

関数呼び出しは次のようにする必要があります。

allocate (&arr);

(ポインターの間接化を簡単にするために、allocate()上記で説明した H2CO3 によって最初に提案された形式を使用して、内部で別の配列へのポインターを宣言して初期化し、そのポインターを に割り当てることができます*arr。)

2D 配列へのポインターだけでなく、配列内の各要素にもメモリを割り当てる必要があることに注意してください。その要素は初期化されていないポインターであるためです。allocate()またはのネストされたループを使用してこれを行うことができますfill_table()

の場合fill_table()、配列へのポインター自体を渡すだけです。プロトタイプは次のようになります。

void fill_table (queue* (*arr) [COLUMNS]);

そして呼び出し:

fill_table (arr);

お役に立てれば。物事を行う最も簡単な方法は、最初に内部ですべてを実行してprocess()から、割り当てと入力部分を独自の関数に分離する方法を確認することです。

于 2013-08-04T10:56:29.780 に答える