Namespaces
Variants

std::vector<T,Allocator>:: reserve

From cppreference.net
void reserve ( size_type new_cap ) ;
(C++20부터 constexpr)

벡터의 용량(재할당 없이 벡터가 보유할 수 있는 총 요소 수)을 new_cap 이상의 값으로 증가시킵니다. 만약 new_cap 이 현재 capacity() 보다 크다면, 새로운 저장 공간이 할당됩니다. 그렇지 않으면 함수는 아무 작업도 수행하지 않습니다.

reserve() 는 벡터의 크기를 변경하지 않습니다.

만약 new_cap capacity() 보다 크면, 모든 반복자( end() 반복자 포함)와 모든 요소에 대한 참조가 무효화됩니다. 그렇지 않으면, 어떤 반복자나 참조도 무효화되지 않습니다.

reserve() 호출 이후에는, 삽입 작업이 벡터의 크기를 capacity() 값보다 크게 만들지 않는 한 재할당이 발생하지 않습니다.

목차

매개변수

new_cap - 벡터의 새로운 용량, 요소 개수 단위
타입 요구사항
-
T MoveInsertable 요구사항을 만족해야 함 * this 에 대해. (C++11부터)

반환값

(없음)

예외

예외가 발생하면, 이 함수는 아무런 효과도 가지지 않습니다 ( strong exception guarantee ).

만약 T 의 이동 생성자가 noexcept 가 아니고 T가 CopyInsertable 이 아닌 경우, * this 에 대해 vector는 예외를 던지는 이동 생성자를 사용합니다. 만약 예외가 발생하면, 보장이 취소되고 효과는 명시되지 않습니다.

(since C++11)

복잡도

컨테이너의 size() 최대 선형 시간 복잡도를 가짐.

참고 사항

reserve() 를 올바르게 사용하면 불필요한 재할당을 방지할 수 있지만, 부적절하게 사용할 경우(예를 들어 모든 push_back() 호출 전에 사용하는 경우) 오히려 재할당 횟수를 증가시킬 수 있으며(용량이 기하급수적으로 증가하는 대신 선형적으로 증가하게 되어), 계산 복잡도가 증가하고 성능이 저하될 수 있습니다. 예를 들어, 임의의 벡터를 참조로 받아 요소를 추가하는 함수는 일반적으로 벡터의 사용 특성을 알지 못하므로 하지 않는 것이 좋습니다 .

범위를 삽입할 때는 일반적으로 범위 버전의 insert() 를 사용하는 것이 바람직합니다. 이는 일련의 reserve() push_back() 을 연속적으로 사용하는 것과 달리 올바른 capacity 증가 동작을 보존하기 때문입니다.

reserve() 는 컨테이너의 용량을 줄이는 데 사용할 수 없습니다; 이를 위해 shrink_to_fit() 가 제공됩니다.

예제

#include <cstddef>
#include <iostream>
#include <new>
#include <vector>
// 디버그 출력을 포함한 최소 C++11 할당자
template<class Tp>
struct NAlloc
{
    typedef Tp value_type;
    NAlloc() = default;
    template<class T>
    NAlloc(const NAlloc<T>&) {}
    Tp* allocate(std::size_t n)
    {
        n *= sizeof(Tp);
        Tp* p = static_cast<Tp*>(::operator new(n));
        std::cout << "allocating " << n << " bytes @ " << p << '\n';
        return p;
    }
    void deallocate(Tp* p, std::size_t n)
    {
        std::cout << "deallocating " << n * sizeof *p << " bytes @ " << p << "\n\n";
        ::operator delete(p);
    }
};
template<class T, class U>
bool operator==(const NAlloc<T>&, const NAlloc<U>&) { return true; }
template<class T, class U>
bool operator!=(const NAlloc<T>&, const NAlloc<U>&) { return false; }
int main()
{
    constexpr int max_elements = 32;
    std::cout << "using reserve: \n";
    {
        std::vector<int, NAlloc<int>> v1;
        v1.reserve(max_elements); // 최소 max_elements * sizeof(int) 바이트 예약
        for (int n = 0; n < max_elements; ++n)
            v1.push_back(n);
    }
    std::cout << "not using reserve: \n";
    {
        std::vector<int, NAlloc<int>> v1;
        for (int n = 0; n < max_elements; ++n)
        {
            if (v1.size() == v1.capacity())
                std::cout << "size() == capacity() == " << v1.size() << '\n';
            v1.push_back(n);
        }
    }
}

가능한 출력:

using reserve: 
allocating 128 bytes @ 0xa6f840
deallocating 128 bytes @ 0xa6f840
not using reserve: 
size() == capacity() == 0
allocating 4 bytes @ 0xa6f840
size() == capacity() == 1
allocating 8 bytes @ 0xa6f860
deallocating 4 bytes @ 0xa6f840
size() == capacity() == 2
allocating 16 bytes @ 0xa6f840
deallocating 8 bytes @ 0xa6f860
size() == capacity() == 4
allocating 32 bytes @ 0xa6f880
deallocating 16 bytes @ 0xa6f840
size() == capacity() == 8
allocating 64 bytes @ 0xa6f8b0
deallocating 32 bytes @ 0xa6f880
size() == capacity() == 16
allocating 128 bytes @ 0xa6f900
deallocating 64 bytes @ 0xa6f8b0
deallocating 128 bytes @ 0xa6f900

결함 보고서

다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.

DR 적용 대상 게시된 동작 올바른 동작
LWG 329 C++98 삽입으로 인해 벡터의 크기가
reserve() 의 가장 최근 호출에서
지정된 크기보다 커지면 재할당이 발생할 수 있음
벡터의 크기가
capacity() 보다 커지는 경우에만
발생함
LWG 2033 C++11 T MoveInsertable 일 것을 요구하지 않음 요구됨

참고 항목

현재 할당된 저장 공간에 보관할 수 있는 요소의 수를 반환합니다
(public member function)
가능한 최대 요소 수를 반환합니다
(public member function)
저장된 요소의 수를 변경합니다
(public member function)
사용되지 않는 메모리를 해제하여 메모리 사용량을 줄입니다
(public member function)