본문 바로가기

Programming/C++

[C++] 3. 메모리관리 / 동적 할당 new & delete (malloc/free in C)

이 포스팅은 윤성우님의 열혈 C++ 프로그래밍 책을 기반으로 작성되었습니다.

메모리관리와 동적할당은 C++에서 매우 중요한 개념이다.
어떻게 보면 이 메모리관리를 효율적으로 잘하는 코드를 짜는 사람이 진정 프로그래밍을 잘하는 사람일 것이다.
하지만 우리는 C나 C++이 아닌 파이썬에서는 이 개념을 쉽게 간과하고 있다.
이유는 간단하다. 파이썬은 C로 만들어진 프로그래밍 언어이며, 개발자들의 효율을 위해 직접 레퍼런스 카운트와 가비지 콜렉션을 이용하여 메모리를 생성 및 해제하며 스스로 메모리를 관리해주기 때문이다.
때문에 파이썬으로 만들어진 프로그램들도 어떻게 코드를 이해하고 짜느냐에 따라 효율이 몇십프로까지 향상될 수 있다.
결론은 메모리관리는 아무리 강조해도 지나치지 않다! 그럼 이제 한번 포스팅을 시작해보자.

동적할당은 다음과 같은 목적에서 도입되었다. 
변수에 얼만큼의 크기가 인풋으로 들어올 지 모를 때!
이 말이 무슨 말이냐, C++에서는 int, double, 혹은 [] array등을 통하여 변수 타입과 크기를 생성 시 선언해준다.
하지만 만약 변수로 1-10000의 크기가 들어올 수 있다고 해서 10000크기로 만들어서 설정을 해놓고 시작하는 것은 1만 들어왔을 때 9999의 메모리 손실을 야기한다는 것이다. 그렇기에 우리는 때에 따라서 프로그램이 돌아가는 동안 input의 크기만큼 메모리를 할당하고 프로그램이 끝날 때 메모리를 해제하는 기가 막힌 방법을 생각해낸 것이다.

New와 Delete

New와 Delete는 C에서의 malloc과 free와 매칭된다.
C++부터 클래스와 객체의 개념이 생겨나면서 완전히 매칭된다고는 볼 수 없지만 그 목적이 비슷하다고 생각하면 좋을 것 같다.
위의 동적할당을 다시 활용해 설명해보면, 우리가 메모리가 동적으로 필요할 때 new를 이용해 요청을 하고 이는 heap이라는 메모리공간의 남아있는 공간의 시작주소를 리턴한다. 주소값을 리턴하기 때문에 포인터를 통해서 읽게 되고, 혹시 문제가 생겼거나 메모리가 꽉 찰 경우 NULL값이 리턴된다.
앞선 포스팅에서 설명했었는데 포인터가 가리키는 곳이 없을 경우 NULL을 가리키게 되며 초기 포인터 선언 시 이를 NULL로 설정해놓는 것이 좋은 습관이다.
사용법을 바로 들여다보자.

int *ptr = new int;
double *ptr1 = new double;
int *arr = new int[10]; //배열의 동적 할당

delete ptr;
delete ptr1;
delete []arr;

이처럼 힙 영역으로의 접근은 주로 포인터로 이루어지는데, 이를 일반 변수로 접근하기 위해서는 그냥 포인터를 참조자 선언해주면 된다.
ex) int &ref = *ptr