Namespaces
Variants

realloc

From cppreference.net
헤더 파일에 정의됨 <stdlib.h>
void * realloc ( void * ptr, size_t new_size ) ;

주어진 메모리 영역을 재할당합니다. ptr 이 NULL이 아닌 경우, 이는 반드시 이전에 malloc , calloc 또는 realloc 으로 할당되었으며 free 또는 realloc 호출로 아직 해제되지 않은 상태여야 합니다. 그렇지 않으면 결과는 정의되지 않습니다.

재할당은 다음 중 하나의 방법으로 수행됩니다:

a) 가능한 경우, ptr 이 가리키는 기존 영역을 확장하거나 축소합니다. 영역의 내용은 새로운 크기와 기존 크기 중 더 작은 크기까지 변경되지 않습니다. 영역이 확장된 경우, 배열의 새로운 부분의 내용은 정의되지 않습니다.
b) new_size 바이트 크기의 새로운 메모리 블록을 할당하고, 새 크기와 기존 크기 중 더 작은 크기만큼의 메모리 영역을 복사한 후 기존 블록을 해제합니다.

충분한 메모리가 없는 경우, 기존 메모리 블록은 해제되지 않고 널 포인터가 반환됩니다.

만약 ptr NULL 인 경우, 동작은 malloc ( new_size ) 를 호출하는 것과 동일합니다.

그렇지 않으면,

new_size 가 0이면, 동작은 구현에 따라 정의됩니다 (널 포인터가 반환될 수 있으며 (이 경우 기존 메모리 블록이 해제될 수도 있고 해제되지 않을 수도 있음), 또는 저장 공간에 접근하는 데 사용할 수 없는 어떤 널이 아닌 포인터가 반환될 수 있음). 이러한 사용법은 권장되지 않습니다 ( C DR 400 를 통해). (C17부터)

(C23 이전)

new_size 가 0이면, 동작은 정의되지 않습니다.

(C23부터)

realloc 는 스레드 안전합니다: 인자를 통해 접근 가능한 메모리 위치만 접근하고 정적 저장소는 접근하지 않는 것처럼 동작합니다.

메모리 영역을 해제하는 free 또는 realloc 의 이전 호출은 동일한 메모리 영역 전체 또는 일부를 할당하는 realloc 을 포함한 모든 할당 함수와 동기화됩니다(synchronizes-with) . 이 동기화는 해제 함수에 의한 메모리 접근 이후, 그리고 realloc 에 의한 메모리 접근 이전에 발생합니다. 각 특정 메모리 영역에 대해 동작하는 모든 할당 및 해제 함수에는 단일 총 순서(single total order)가 존재합니다.

(C11부터)

목차

매개변수

ptr - 재할당할 메모리 영역에 대한 포인터
new_size - 바이트 단위의 새로운 배열 크기

반환값

성공 시, 새로 할당된 메모리의 시작 부분을 가리키는 포인터를 반환합니다. 메모리 누수를 방지하려면 반환된 포인터는 free 또는 realloc 으로 해제되어야 합니다. 원본 포인터 ptr 는 무효화되며, 이에 대한 모든 접근은 정의되지 않은 동작입니다(재할당이 제자리에서 이루어진 경우에도).

실패 시, 널 포인터를 반환합니다. 원본 포인터 ptr 는 유효한 상태로 남아 있으며, free 또는 realloc 로 할당 해제해야 할 수 있습니다.

참고 사항

원래(C89에서), 다음과 같은 코드를 수용하기 위해 제로 크기 지원이 추가되었습니다.

OBJ *p = calloc(0, sizeof(OBJ)); // "zero-length" 플레이스홀더
/*...*/
while (1)
{
    p = realloc(p, c * sizeof(OBJ)); // 크기가 안정화될 때까지 재할당
    /* c를 변경하거나 루프를 탈출할 수 있는 코드 */
}

예제

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void print_storage_info(const int* next, const int* prev, int ints)
{
    if (next)
        printf("%s location: %p. Size: %d ints (%ld bytes).\n",
               (next != prev ? "New" : "Old"), (void*)next, ints, ints * sizeof(int));
    else
        printf("Allocation failed.\n");
}
int main(void)
{
    const int pattern[] = {1, 2, 3, 4, 5, 6, 7, 8};
    const int pattern_size = sizeof pattern / sizeof(int);
    int *next = NULL, *prev = NULL;
    if ((next = (int*)malloc(pattern_size * sizeof *next))) // 배열 할당
    {
        memcpy(next, pattern, sizeof pattern); // 배열 채움
        print_storage_info(next, prev, pattern_size);
    }
    else
        return EXIT_FAILURE;
    // 다음 값을 새로운 저장소 크기로 사용하여 순환 재할당
    const int realloc_size[] = {10, 12, 512, 32768, 65536, 32768};
    for (int i = 0; i != sizeof realloc_size / sizeof(int); ++i)
    {
        if ((next = (int*)realloc(prev = next, realloc_size[i] * sizeof(int))))
        {
            print_storage_info(next, prev, realloc_size[i]);
            assert(!memcmp(next, pattern, sizeof pattern));  // 패턴 유지 확인
        }
        else // realloc 실패 시 원본 포인터 해제 필요
        {
            free(prev);
            return EXIT_FAILURE;
        }
    }
    free(next); // 최종적으로 저장소 해제
    return EXIT_SUCCESS;
}

가능한 출력:

New location: 0x144c010. Size: 8 ints (32 bytes).
Old location: 0x144c010. Size: 10 ints (40 bytes).
New location: 0x144c450. Size: 12 ints (48 bytes).
Old location: 0x144c450. Size: 512 ints (2048 bytes).
Old location: 0x144c450. Size: 32768 ints (131072 bytes).
New location: 0x7f490c5bd010. Size: 65536 ints (262144 bytes).
Old location: 0x7f490c5bd010. Size: 32768 ints (131072 bytes).

참고문헌

  • C23 표준 (ISO/IEC 9899:2024):
  • 7.22.3.5 realloc 함수 (p: TBD)
  • C17 표준 (ISO/IEC 9899:2018):
  • 7.22.3.5 realloc 함수 (p: 254)
  • C11 표준 (ISO/IEC 9899:2011):
  • 7.22.3.5 realloc 함수 (p: 349)
  • C99 표준 (ISO/IEC 9899:1999):
  • 7.20.3.4 realloc 함수 (p: 314)
  • C89/C90 표준 (ISO/IEC 9899:1990):
  • 4.10.3.4 realloc 함수

참고 항목

C++ 문서 for realloc