2011-09-19 3 views
2

나는 다음과 같은 코드를 가지고 :realloc은 메모리를 확장하거나 메모리 문제를 일으킬 수 있습니까?

는 출력
#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 : 사실, 아래의 각 답변은 저에게 귀중한 정보를 제공했습니다. 그리고 받아들이기만 한 응답을 선택해야하기 때문입니다. 위의 코드를 수정 한 코드를 선택했습니다!

답변

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); 
+0

당신은 더 나은 성공적인 realloc을 한 후 그것을 해제하지 않는 게 좋을() – wildplasser

+0

@wildplasser : 당신은 당신이해야 더 이상 필요하지 않을 때; 나는 그'/ * ... * /'를 분명히 할 것이다. –

+0

알지만, 초보자를 혼란스럽게 할 수 있습니다. 이 쓰레드는 사용 후 free() 메모리가 아니라 realloc()에 관한 쓰레드이다. – wildplasser

4

두 가지 경우가 있습니다.

  • realloc을 실패 : 당신은
  • realloc을 성공 원래 포인터를 해제 할 책임이 있습니다 : 당신은

참고 반환 된 포인터를 자유롭게에만 책임 같습니다 realloc 함수는 확장 보장 할 수 없습니다 메모리 위치. 사실 내가 원래 malloc에 ​​의해 생성 된 위치 을 확보 외에 explicitly-이 위치를 확보해야한다 0

2

의 크기를 선택하여 메모리를 축소 할 수 있습니다?

아니요 realloc이 처리해야합니다. 메모리가 새로운 주소 공간에 재 할당되는 경우에도, realloc이 성공하면 malloc을 사용하여 이전에 할당 된 메모리가 자동으로 해제됩니다. 세 가지 중 하나를 수행 할 수

1

realloc을은 :

1)는 이전의 메모리가 주위를 shufle TTO 필요없이 확장 할 수 있음을 발견한다.

2) 귀하의 요청을 만족시킬 수는 있지만 메모리 개체는 다른 곳에 보관해야합니다.

3) 실패 할 수 있습니다.

귀하의 경우 1) 일이 일어난 것 같습니다. 편집 : 다른 포인터를 반환했기 때문에 2)

BTW 3) NULL을 반환합니다. 아무 일도 없었고 포인터가 여전히 유효한 이전 개체를 가리 킵니다.