2

CremoveでJavaのforに相当するものを書こうとしています.ArrayList

これが私のコードです。index がリスト内の有効なインデックスであると想定しています。

void arrayListRemove(ArrayList* list, int index){
  int i;
  if (arrayListSize(list)==1){
    list->size = 0;
    free(list->data);
    list->data = NULL;
  } else {
    for(i=index;i<arrayListSize(list)-1;i++){
      list->data[i] = list->data[i+1];
    }
    list->data = realloc(list->data, (arrayListSize(list) - 1) * sizeof(void*));
    if (list->data != NULL){
      --list->size;
    } else {
      exit(1);
    }
  }
}

これは正しいです?

コードはarrayListSize(list) == 1チェックなしで機能しますか? つまり、 arrayListrealloc(list->data, 0)を解放しますか? 何realloc(ptr, 0)ができるかについて、オンラインで相反するものを見てきました。

4

1 に答える 1

3

arrayListSize(list) == 1私はケースを残します。の動作に依存しないrealloc(ptr, 0)ことは賢明なようであり、一般的に明示的な を使用することにより、コードがより明確になりfreeます。

さらにいくつかのメモ:

  • を使用する場合reallocは、必ず戻り値をtmp変数に取り込んでください。失敗した場合は、元のポインターをそのままにして、元にrealloc戻すことができます。NULLこれを行うと、元のポインターが失われるため、失敗しptr = realloc(ptr);たときにメモリ リークが発生する可能性があります。realloc代わりに、次のイディオムを使用します。

    tmp = realloc(ptr, newSize);
    if (tmp != NULL)
        ptr = tmp;
    else handleError();
    
  • freeリストから要素を削除するときに、リストの要素が必要ですか? 配列dataはポインタで構成されていfreeます。削除された要素を呼び出さないことでメモリ リークが発生していますか? 当然、これは Java 実装では必要ありません。リストに含まれているオブジェクトへの参照のみが含まれている場合は、free削除時にそれらを参照する、関数でポインターを返して呼び出し元に任せてメモリを処理する必要があります。

  • 通常、メモリが実際reallocに制約されているプラ​​ットフォームを使用していない限り、リストを縮小するために使用する必要はありません。また、その場合でも、削除されたリスト要素ごとに割り当てられたブロックを縮小する必要はおそらくありません。割り当てられたブロックを複数の要素で拡大/縮小することを好みます。

  • これは本当に厄介ですが、これは API メソッドでありsize、データ構造のメンバーを使用してリストの長さを追跡しているためsize、別の API メソッドに依存するのではなく、全体で使用することもできますarrayListSize

于 2012-07-25T18:59:47.800 に答える