1

ここで学んだことを使用して: How to use realloc in a function in C、私はこのプログラムを書きました。

int data_length; // Keeps track of length of the dynamic array.
int n; // Keeps track of the number of elements in dynamic array.

void add(int x, int data[], int** test)
{

    n++;

    if (n > data_length)
    {
        data_length++;
        *test = realloc(*test, data_length * sizeof (int));
    }

    data[n-1] = x;

}

int main(void)
{

    int *data = malloc(2 * sizeof *data);

    data_length = 2; // Set the initial values.
    n = 0;

    add(0,data,&data);
    add(1,data,&data);
    add(2,data,&data);

    return 0;
}

dataこのプログラムの目標は、値を追加し続けることができる動的配列を作成することです。に値を追加しようとすると、値dataがいっぱいの場合、realloc を使用して配列の長さが増加します。

質問

このプログラムはコンパイルされ、実行時にクラッシュしません。ただし、 を出力するdata[0]data[1]data[2]が得られ0,1,0ます。番号2は配列に追加されませんでした。

これは私の間違った使い方によるものreallocですか?

追加情報

このプログラムは、後でさまざまな数の「追加」および場合によっては「削除」機能で使用されます。また、realloc失敗した ( である) かどうかを確認する必要があることはわかっNULLていますが、簡単にするためにここでは省略しています。

私はまだ C の学習と実験を行っています。しばらくお待ちいただきありがとうございます。

4

3 に答える 3

2

の使用に問題があります data。これは、古い配列のアドレスを指しているためです。その後、電話をかけるとrealloc、このエリアは解放されます。したがって、次の命令で無効なアドレスにアクセスしようとしています。これにより、未定義の動作が発生します。

dataまた、このポインタを使用する必要はありません。test十分なものです。

(*test)[n-1] = x;
于 2012-12-06T18:12:00.600 に答える
1

dataに2回渡す必要はありませんadd

あなたはコーディングすることができます

void add(int x, int** ptr)
{
  n++;
  int *data = *ptr;
  if (n > data_length) {
    data_length++;
    *ptr = data = realloc(oldata, data_length * sizeof (int));
    if (!data) 
      perror("realloc failed), exit(EXIT_FAILURE);
  }
  data [n-1] = x;
}

しかし、それは非常に非効率的です。たまにreallocしか電話をかけないでください。あなたは例えば持つことができます

     data_length = 3*data_length/2 + 5;
     *ptr = data = realloc(oldata, data_length * sizeof (int));
于 2012-12-06T18:11:44.527 に答える
1

POSIX realloc specificationを見てみましょう。

説明には次のように書かれています。

メモリ オブジェクトの新しいサイズがオブジェクトの移動を必要とする場合、オブジェクトの以前のインスタンス化のための領域が解放されます。

戻り値(強調を追加)には次のことが記載されています。

0 以外のサイズで正常に完了すると、realloc() は (移動された可能性がある) 割り当てられた領域へのポインターを返します。

ポインタが変化するかどうかを確認できます。

int *old;
old = *test;
*test = realloc(*test, data_length * sizeof(int));
if (*test != old)
    printf("Pointer changed from %p to %p\n", old, *test);

コードが 2 つの異なる名前で「同じ」メモリを参照しているため、この変更の可能性はうまく作用しない可能性がdataあり*testます。*test変更された場合dataでも、メモリの古いチャンクを指します。

于 2012-12-06T18:24:07.200 に答える