2

次のコードがあります。

#include <stdio.h>
#include <stdlib.h>
#define OUT

void getDataFromServer(OUT int** array, OUT int* size)
{
    static int tmpArr[] = {0x00, 0x01, 0x02, 0x03,  0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
                        0x10, 0x11, 0x12, 0x13,  0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
    *size = sizeof tmpArr / sizeof(int);
    printf("Before realloc: %p\n", *array);
    *array = realloc(*array, sizeof(*array) * *size);
    printf("After realloc : %p\n", *array);
    int i=0;
    for (; i < *size; i++)
    {
        (*array)[i] = tmpArr[i];
    }
}

int main(void)
{
    int size = 0;
    int* dataFromServer = malloc(sizeof *dataFromServer);
    printf("in main: %p\n", dataFromServer);
    getDataFromServer(&dataFromServer, &size);

    int x;
    for (x=0; x < size; x++)
        printf("%d ", dataFromServer[x]);
    printf("\n\n");
    free(dataFromServer);
    return 0;
}

出力:

in main: 003F1708
Before realloc: 003F1708
After realloc : 003F3430
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

出力から、reallocは新しいメモリ アドレスへのポインタを返します。

それで問題は、オリジナルによって作成された場所を解放する以外に、この場所を明示的に解放する必要があるmallocかどうかです。

または、上記のコードが望んでいたことを実行していJust expand the memory location reserved previouslyますか?

ありがとう。

EDIT: 実際、以下の各回答は貴重な情報を提供してくれました。そして、受け入れる回答を 1 つだけ選択する必要があるためです。上記のコードを修正したものを選択しました!

4

4 に答える 4

5

呼び出しreallocてポインターが返された後は、前のポインターを忘れて、「新しい」ポインターを保持する必要があります。

reallocサイズを変更した場合はそれを返しreallocます。メモリに新しいスペースを割り当てて以前の内容をコピーした場合は、古いポインターを解放して新しいポインターを返します。

ただしrealloc、 (コードで行っているように)への呼び出しの結果で古いポインターを上書きしないでください: 実際には、realloc失敗すると戻り、古いポインターを解放NULLません。保存すると、そのメモリにアクセスする唯一の方法が失われfree、メモリ リークが発生します。したがって、「標準的な」呼び出し方法reallocは次のとおりです。

/* assuming myPtr contains the malloced memory */
void * tempPtr=realloc(myPtr, newSize);
if(tempPtr==NULL)
{
    /* realloc failed, handle the error and, if aborting, free myPtr */
}
else
    myPtr = tempPtr;

/* ... */

/* when you no longer need it free the memory */
free(myPtr);
于 2011-09-19T21:54:46.660 に答える
4

ここには 2 つのケースがあります。

  • Realloc の失敗: 元のポインターを解放することのみを担当します。
  • Realloc の成功: 返されたポインターを解放することのみを担当します。

注: このrealloc関数は、メモリ ロケーションを拡張することは保証されていません。実際には、サイズ 0 を選択することでメモリを縮小するために使用できます。

于 2011-09-19T21:50:03.247 に答える
2

元のmallocによって作成された場所を解放する以外に、この場所を明示的に解放する必要がありますか?

いいえ、 realloc がそれを処理する必要があります。メモリが新しいアドレス空間に再割り当てされた場合でも、realloc が成功すると、以前に malloc で割り当てられたメモリは自動的に解放されます。

于 2011-09-19T21:51:04.040 に答える
1

Realloc は、次の 3 つのいずれかを行うことができます。

1) 以前の記憶をシャッフルしなくても拡張できることがわかります。

2) 要求を満たすことはできますが、メモリ オブジェクトを別の場所に配置する必要があります。

3) 失敗する可能性があります。

あなたの場合、1)が起こったようです。編集:別のポインターを返したので、2を選択しました)

ケース3のところで、それはNULLを返します。何も起こらず、ポインターはまだ有効な古いオブジェクトを指しています。

于 2011-09-19T21:53:32.577 に答える