[C++] 메모리 할당
[C++] 메모리 할당
C++ 프로그램들은 실행하는 동안 변수처럼 새로운 개체를 만들 때 메모리를 할당해야한다. 그리고 메모리 구조는 크게 데이터, 코드, 힙, 스택 영역으로 분류하며 각각의 역할이 정해져있다.
메모리 할당을 정리하기에 앞서 메모리 구조에 대해 알아볼 필요가 있다. 스택과 힙에 대해서 먼저 알아보겠다.
스택 (Stack)
함수에 전달되는 인자(매개변수), 함수내에 저장되는 지역 변수 등이 저장되는 곳이다.
▸ 한정된 범위 내에서 임시적으로 사용될 때 좋다.
▸ LIFO(Last In First Out)구조를 가지며, 가장 나중에 들어온 것이 먼저 나가는 구조이다.
▸ 제한된 크기를 가지고 있어 용량을 초과하는 개체를 넣으면 스택오버플로우 현상이 발생한다.
힙 (Heap)
사용자가 직접 관리할 수 있는 메모리 영역이다. 즉, 프로그램이 실행되는 런타임 동안 동적으로 할당이 가능한 공간이다.
스택과 힙의 여러차례 할당 / 해제 가 이루어진 후를 보면 힙에서 더 많은 조각이나 있는 영역을 볼수 있다. 이것은 메모리 단편화라고 부르며 공간을 잡아먹는 문제를 초례한다.
▸ new, alloc을 통해서 할당을하며 delete, free를 통해 해제를 한다. 해제 전까지는 지속적으로 사용 가능하다.
▸ 스택과 비교했을 때 힙은 혼란스러운 공간일 수 있으나 무엇이든지 얻을 수 있는 공간이다.
▸ 스택과는 다르게 임의의 순서로 메모리 할당과 해제가 이루어 진다.
힙의 문제점
▸ 할당의 성능 : 메모리를 요청 후 리턴되는 시간이 플랫폼에 따라 시간 차가 있을 수 있다.
▸ 메모리 단편화 : 위에 그림에서도 확인했듯이 메모리는 있으나 충분한 크기의 메모리 공간을 찾지 못해 할당을 실패할 수 있다.
▸ 메모리 누수 : 메모리를 할당하면 해제를 직접시켜줘야한다. 이를 지키지 않았을 경우 시간이 지날수록 프로그램이 느려지는 상황이 발생할 수 있다.
정적 할당
#define MAX_COUNTS 9999
int* intArr[MAX_COUNTS];
#define GEOSIZE (8 * 1024 * 1024)
byte* s_GeoBuffer[GEOSIZE];
int main()
{
int maxCount = MAX_COUNTS;
return 0;
}
정적으로 메모리를 할당하면 stack 영역에 할당되며, 함수를 빠져나갈 때 소멸이 된다. 프로그램 컴파일 시 영역의 크기 할당을 받기 때문에 컴파일 이후에는 크기가 변경될 수 없다.
정적 할당의 장점
▸ 동적 할당에 따르는 성능 저하가 없으며 프로그램이 실행되는 동안 변경이 없기에 메모리 단편화 현상이 발생하지 않는다.
▸ 얼만큼의 메모리가 어떠한 데이터형으로 이용되고 있는지 확인이 쉽다.
정적 할당의 단점
▸ 많은 양의 메모리를 낭비할 수 있다.
▸ 길 잃은 포인터의 발생 확률은 낮으나 포인터가 가리키는 메모리가 잘못되는 현상이 발생할 수 있다.
▸ 객체가 정적으로 초기화 되어야한다.
정적 할당은 상호작용이 없는 공간. 즉, 구현하는 공간이 정적인 구성을 가지고 있을때 사용하도록 하자.
동적 할당
int main()
{
int* pInt = new int;
double* pDouble = new double;
delete pInt;
delete pDouble;
return 0;
}
위에서도 말했듯이 동적으로 메모리를 할당하면 런타임 동안 힙 영역에 메모리를 할당 받게된다.
동적 할당은 스택보다 넓은 힙의 공간에서 보다 자유롭게 할당 / 해제를 할 수 있다는 장점을 가지고 있으나 그만큼 메모리 단편화나 해제를 해주지 못했을 경우 메모리 누수같은 상황이 발생할 수 있다.
메모리 풀 (Memory Pool)
프로그램 런타임 시에 한 가지 크기의 개체를 할당하는데 이용하기 위해 미리 할당된 메모리 공간을 만들어 놓는것이다.
class MemoryPool {
public:
MemoryPool(size_t nObjectSize);
~MemoryPool();
void Alloc(size_t nSize);
void Free(void* p, size_t nSize);
}
메모리 풀의 장점
▸ 성능 저하가 없다.
▸ 메모리 단편화가 없다.
▸ 할당을 한번만 한다.
▸ 사용한 개체를 각각 해제하지 않아도 풀 내에서 한번에 제거 가능하다.
메모리 풀의 단점
▸ 적절하게 크기를 조절하지 않으면 공간을 차지하고 있을 수 있다.
정적 할당은 방법은 간단하고 성능저하가 없지만 유연성이 부족하고 공간의 제약이 있으며,
동적 할당은 정적 할당에 비해서 유연하지만 다양한 문제점들을 초례할 수 있는 위험성 또한 갖고 있다.