C++ Memory and Optimization
[C++ 자료구조] 벡터의 동적할당 시 메모리 확장 방식
doyyy_0
2024. 12. 21. 12:19
벡터는 push_back같이 메모리 공간이 더 필요할 때, 해당 공간만큼만 늘리지 않습니다. 예를들어 vector<int> v가있다고 했을 때, 메모리를 차지하는 첫 공간은 0byte입니다. 하지만 필요하면 1byte -> 2bytes-> 4bytes->8bytes->16bytes이렇게 제곱으로 늘어납니다. 왜냐하면 공간이 필요할 때 마다 현재 차지하고 있는 공간의 두배를 할당해버리기 때문이죠.
다음 두 코드를 비교해 봅시다.
//첫번째 케이스
vector<int> v;
for(int i = 0 ; i< 100000; i++)
{
v.push_back(0);
}
//두번째 케이스
vector<int> v(100000,0);
두번째 케이스는 int가 4bytes이고 100000번 할당하니 그냥 4*100000 bytes만 필요로합니다.
하지만 첫번째 케이스에서는 필요할때마다 벡터의 공간을 늘려주는 방식이니 최악의 경우 두배로 메모리 공간이 필요할 수 있습니다.
왜 굳이 벡터가 제곱 형식으로 메모리를 할당하냐면, 재할당 횟수를 최소화하여 속도 효율성을 끌어 올리기 위함인 것 같습니다. 즉 두배로 늘리면 한 동안 여유 공간이 생기기 때문이죠.
하지만 2차원 이상의 배열은 약간 조심해야합니다. 다음의 코드를 봅시다.
vector<vector<int>> v(100000,vector<int>(3,0));
12bytes*100000이 할당되어야할 것 같지만, 벡터의 특성상 동적으로 메모리를 관리하기 때문에, 벡터내부에서 메모리를 더 크게 잡아먹는 부분이 있는 것 같습니다. visual studio 디버그에서 추적해보니 22Mb나 잡아먹습니다.
따라서 2차원 이상의 배열은 메모리 소모가 심하니,
vector<int>v (300000);
for(int i = 0 ; i< 100000; i++)
{
for(int j = 0 ; j < 3; j++)
{
cout << v[3*i+j];
}
}
이런식으로 1차원 배열을 2차원처럼 생각해서 쓸 수 있는 방법이 있겠습니다.