web-dev-qa-db-ja.com

Cで配列のサイズを変更する

作成しているゲームに構造体の配列が必要ですが、配列を固定サイズに制限したくありません。必要に応じてreallocを使用して配列を大きくする方法はあると聞いていますが、これに関する実用的な例は見つかりません。

誰か私にこれを行う方法を教えてもらえますか?

18
Gary

配列を作成することから始めます。

structName ** sarray = (structName **) malloc(0 * sizeof(structName *));

常に個別にサイズを追跡します。

size_t sarray_len = 0;

増加または切り捨てるには:

sarray = (structName **) realloc(sarray, (sarray_len + offset) * sizeof(structName *));

次に、サイズを設定します。

sarray_len += offset;

お役に立てて幸いです。

30
Delan Azabani

realloc関数は、配列を拡大または縮小するために使用できます。配列が大きくなると、既存のエントリはその値を保持し、新しいエントリは初期化されません。これはインプレースで拡大するか、それが不可能な場合は、メモリ内の別の場所に新しいブロックを割り当てます(そして、舞台裏で、すべての値を新しいブロックにコピーして古いブロックを解放します)。

最も基本的な形式は次のとおりです。

// array initially empty
T *ptr = NULL;

// change the size of the array
ptr = realloc( ptr, new_element_count * sizeof *ptr );

if ( ptr == NULL )
{
    exit(EXIT_FAILURE);
}

乗算は、reallocがバイト数を期待するためですが、配列には常に適切な数の要素が必要です。このreallocのパターンは、Tの元の宣言以外のコードでptrを繰り返す必要がないことを意味します。

exitを実行する代わりに、プログラムが割り当てエラーから回復できるようにしたい場合は、古いポインタをNULLで上書きするのではなく、保持する必要があります。

T *new = realloc( ptr, new_element_count * sizeof *ptr );

if ( new == NULL )
{
    // do some error handling; it is still safe to keep using
    // ptr with the old element count
}
else
{
    ptr = new;
}

reallocを介して配列を圧縮しても、実際にはオペレーティングシステムにメモリが返されない場合があることに注意してください。メモリは引き続きプロセスによって所有され、mallocまたはreallocへの今後の呼び出しで使用できる場合があります。

12
M.M

から http://www.cplusplus.com/reference/clibrary/cstdlib/realloc/

/* realloc example: rememb-o-matic */
#include <stdio.h>
#include <stdlib.h>

int main ()
{
  int input,n;
  int count=0;
  int * numbers = NULL;

  do {
     printf ("Enter an integer value (0 to end): ");
     scanf ("%d", &input);
     count++;
     numbers = (int*) realloc (numbers, count * sizeof(int));
     if (numbers==NULL)
       { puts ("Error (re)allocating memory"); exit (1); }
     numbers[count-1]=input;
  } while (input!=0);

  printf ("Numbers entered: ");
  for (n=0;n<count;n++) printf ("%d ",numbers[n]);
  free (numbers);

  return 0;
}
8