본문 바로가기
프로그래밍/C++

C++ ] 연속된 메모리 공간에 저장되는 벡터의 메모리 재할당 빈도

by eteo 2023. 10. 6.

 

 

 

C++의 std::vector는 동적 배열로 구현되어 있어, 내부적으로 메모리를 할당하고 관리하는데 요소를 연속된 메모리 공간에 저장하는 것을 보장한다. 때문에 데이터에 접근할 때 빠른 속도를 제공하고, C스타일 배열 접근 방식을 써서 효율적으로 사용할 수도 있다.

 

vector에 요소를 계속 추가하면 vector는 내부적으로 메모리를 다시 할당하고 복사해 옮기는 작업을 수행하는데 이를 재할당이라고 한다. 재할당은 vector의 현재 capacity(용량)와 size(크기)를 비교하여 추가 요소를 수용하기 부족하다고 판단되는 경우 발생할 수 있다.

 

메모리 재할당은 비용이 높은 작업이고 벡터가 자주 재할당되면 성능이 저하될 수 있기 때문에 이를 최소화하기 위해 reserve()를 사용하여 용량을 예약하는 방법을 쓸 수 있다.

 

std::vector<int> myVector;
myVector.reserve(100); // 최소한 100개의 요소를 수용할 용량 예약
// size는 0이고 capacity는 100인 벡터가 된다.

 

 

 

 

 

그럼 벡터의 메모리 재할당은 언제, 얼마나 자주 일어날까?

 

아래와 같은 코드로 테스트 해봤다.

 

#include <iostream>
#include <vector>

using namespace std;

int main() {
    vector<int> myVector;
    int capaBefore = myVector.capacity();

    for (int i = 1; i <= 100; ++i) {
        
        myVector.push_back(i);
        if(capaBefore != myVector.capacity())
        {
            capaBefore = myVector.capacity();
            cout << "Capa has changed! " << "Size: " << myVector.size() << ", Capacity: " << myVector.capacity() << endl;
        }
    }
    
    myVector.clear();
    cout << "After Cleared! "<< "Size: " << myVector.size() << ", Capacity: " << myVector.capacity() << endl;

    return 0;
}

 

 

 

 

capacity는 1, 2, 4, 8, 16, 32, 64, 128, ... 이렇게 2의 거듭제곱으로 증가하며 재할당 된다.

 

그리고 capacity가 증가하는 순간은 size가 (capacity/2) + 1 되는 순간이다.

 

또한 vector의 size가 줄어들더라도 capacity가 줄어들지 않은 것을 확인할 수 있다.

 

 

 

 

 

 

 

 

 

 

만약 reserve()를 사용해서 용량을 미리 확보해 놓은 경우 요소가 추가되면 capacity는 어떻게 증가될까?

 

 

#include <iostream>
#include <vector>

using namespace std;

int main() {

    
    vector<int> myVector;
    const int minCapacity = 20;
    myVector.reserve(minCapacity);
    int capaBefore = myVector.capacity();

    for (int i = 1; i <= 100; ++i) {
        
        myVector.push_back(i);
        if(capaBefore != myVector.capacity())
        {
            capaBefore = myVector.capacity();
            cout << "Capa has changed! " << "Size: " << myVector.size() << ", Capacity: " << myVector.capacity() << endl;
        }
    }

    return 0;
}

 

 

현재의 2배 크기로 재할당 되는 것을 알 수 있다.

 

capacity가 증가하는 순간은 똑같이 size가 (capacity/2) + 1 이 될 때이다.