Namespaces
Variants

std:: realloc

From cppreference.net
< cpp ‎ | memory ‎ | c
Memory management library
( exposition only* )
Allocators
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Memory resources
Uninitialized storage (until C++20)
( until C++20* )
( until C++20* )
( until C++20* )

Garbage collector support (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
헤더 파일에 정의됨 <cstdlib>
void * realloc ( void * ptr, std:: size_t new_size ) ;

주어진 메모리 영역을 재할당합니다 ( 대상 영역에서 객체를 암시적으로 생성 합니다). 이는 반드시 이전에 std::malloc , std::calloc 또는 std::realloc 으로 할당되었고 아직 std::free 로 해제되지 않은 상태여야 합니다. 그렇지 않으면 결과가 정의되지 않습니다.

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

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

메모리가 충분하지 않으면, 기존 메모리 블록은 해제되지 않고 null 포인터가 반환됩니다.

만약 ptr 가 널 포인터인 경우, 이 동작은 std:: malloc ( new_size ) 를 호출하는 것과 동일합니다.

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

다음 함수들은 스레드 안전성을 요구합니다:

특정 저장 단위를 할당하거나 해제하는 이러한 함수들의 호출은 단일 전체 순서로 발생하며, 각 해제 호출은 이 순서에서 다음 할당(있는 경우)에 대해 happens-before 관계를 가집니다.

(C++11부터)

목차

매개변수

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

반환값

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

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

참고 사항

재할당은 바이트 단위 복사를 수반할 수 있으므로(영역을 확장하든 축소하든 관계없이), 해당 객체들이 TriviallyCopyable 타입이어야 하는 것은 필요 조건(충분 조건은 아님)입니다.

일부 비표준 라이브러리는 "BitwiseMovable" 또는 "Relocatable"이라는 타입 특질을 정의하는데, 이는 다음과 같은 특성을 갖지 않는 타입을 설명합니다:

  • 외부 참조 (예: 다른 요소에 대한 참조를 보유하는 리스트나 트리의 노드), 및
  • 내부 참조 (예: 다른 멤버의 주소를 보유할 수 있는 멤버 포인터).

이러한 유형의 객체는 복사 생성자가 trivial하지 않은 경우에도 해당 저장 공간이 재할당된 후에 접근할 수 있습니다.

예제

#include <cassert>
#include <cstdlib>
#include <new>
class MallocDynamicBuffer
{
    char* p;
public:
    explicit MallocDynamicBuffer(std::size_t initial = 0) : p(nullptr)
    {
        resize(initial);
    }
    ~MallocDynamicBuffer() { std::free(p); }
    void resize(std::size_t newSize)
    {
        if (newSize == 0) // 이 검사는 엄밀히 필요하지 않지만,
        {
            std::free(p); // C에서 크기가 0인 realloc은 사용이 권장되지 않음
            p = nullptr;
        }
        else
        {
            if (void* mem = std::realloc(p, newSize))
                p = static_cast<char*>(mem);
            else
                throw std::bad_alloc();
        }
    }
    char& operator[](size_t n) { return p[n]; }
    char operator[](size_t n) const { return p[n]; }
};
int main()
{
    MallocDynamicBuffer buf1(1024);
    buf1[5] = 'f';
    buf1.resize(10); // 축소
    assert(buf1[5] == 'f');
    buf1.resize(1024); // 확장
    assert(buf1[5] == 'f');
}

참고 항목

C 문서 참조 realloc