web-dev-qa-db-ja.com

Cの関数でreallocを使用する方法

ここで学んだことを基に: Cの関数を使用した動的配列の操作

void test(int data[])
{
    data[0] = 1;    
}    

int main(void)
{    
    int *data = malloc(4 * sizeof *data);

    test(data);

    return 0;
}

これは正常に機能します。ただし、関数でreallocを使用しようとしています。

void increase(int data[])
{
    data = realloc(data, 5 * sizeof *data);    
}

これは準拠しますが、実行時にプログラムがクラッシュします。

質問

関数でreallocを使用するにはどうすればよいですか?

reallocの結果を変数に割り当て、最初にNULLかどうかを確認する必要があることを理解しています。これは単純化された例です。

32
Legendre

int*(配列)の値を変更したいので、increase関数にそのポインターを渡す必要があります。

void increase(int** data)
{
    *data = realloc(*data, 5 * sizeof int);
}

コードを呼び出すと、次のようになります。

int *data = malloc(4 * sizeof *data);
/* do stuff with data */
increase(&data);
/* more stuff */
free(data);
30
simonc

ポインターと配列の違いに留意してください。
配列はスタック内のメモリのチャックであり、それだけです。配列がある場合:

int arr[100];

この場合、arrはメモリのアドレスですが、&arrはメモリのアドレスでもあり、そのメモリのアドレスは一定であり、どの場所にも格納されません。したがって、arrは何かを指す変数ではないため、arr = NULLとは言えません。これは単なるシンボリックアドレスです:配列の開始位置のアドレス。代わりに、ポインタは独自のメモリを持ち、メモリアドレスを指すことができます。

Int []をint *に変更するだけで十分です。
また、変数はコピーによって渡されるため、関数にint **を渡す必要があります。

Reallocの使用方法については、すべての教訓的な例に以下が含まれます。

  1. Reallocを使用します。
  2. NULLかどうかを確認します。この場合、perrorを使用してプログラムを終了します。
  3. NULLでない場合は、割り当てられたメモリを使用します。
  4. 不要になったらメモリを解放します。

それはいい例です:

int* chuck= (int*) realloc (NULL, 10*sizeof(int)); // Acts like malloc,
              // casting is optional but I'd suggest it for readability
assert(chuck);
for(unsigned int i=0; i<10; i++)
{
    chunk[i]=i*10;
    printf("%d",chunk[i]);
}
free(chunk);
7
Ramy Al Zuhouri

両方のコードには非常に問題があります。同じポインターを使用してreallocからの送受信を行うと、失敗するとポインターを失い、後で解放できます。

あなたはこのようなことをする必要があります:

{... ...

more = realloc(area , size);
if( more == NULL )
    free(area);
else
    area=more;

... ...

}

4
user8036942