Programming/C&CPP

C++ 동적 할당 new / delete 사용시 주의점

psychoria 2014. 12. 6. 18:30
반응형

C++은 메모리 관리가 상당히 까다로운 언어입니다.

사용자가 메모리의 동적 할당과 해제를 할 책임이 있기 때문입니다.

조금만 실수하면 메모리 누수나, 메모리 접근 위반으로 프로그램이 강제 종료됩니다.

메모리 누수란 프로그램이 종료되기 전에 할당한 모든 메모리가해제가 되어야 하는데

할당된 메모리가 해제가 되지 않을 때 발생하는 문제입니다.

메모리 접근 위반은 초기화되지 않은 포인터 혹은 할당된 범위 밖을 호출할 때 발생합니다.

초기화되지 않은 포인터는 어떻게 작동할 지 예측을 할 수 없습니다.

대부분의 경우는 프로그램이 강제 종료됩니다.

new 사용하여 메모리를 동적 할당할 시에 주의할 점은 다음과 같습니다.

new는 delete로 해제하고, new[]는 delete[]로 해제해줘야 한다는 것입니다.

간단한 규칙으로 보이지만 신경쓰지 않고 사용하다가 잘못 사용되는 경우가 생깁니다.

이럴 경우 디버깅에 오랜 시간을 투자해야 할 수도 있기 때문에 꼭 다시 한 번 상기하시기 바랍니다.

Effective C++에서는 다음 그림을 들어서 new를 delete[]로 해제했을 때나

new[]를 delete로 해제했을 때의 위험성을 설명합니다.

한 개의 객체를 동적 할당할 때와 객체의 배열로 동적 할당할 때의 구조가 다르다는 의미입니다.

그렇기 때문에 정상적으로 메모리의 해제가 이루어지지 않을 수 있다는 것입니다.

실제 코드를 통해서 알아보도록 하겠습니다.

console project에서 확인하기 위해서 다음과 같은 코드를 추가합니다.

#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>

#include <crtdbg.h>를 하기 이전에 #define _CRTDBG_MAP_ALLOC이 선언되어야 합니다.

#include <iostream>
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
using namespace std;

int main()
{
	char* pC = new char[10];
	_CrtDumpMemoryLeaks();

	delete[] pC;

	_CrtDumpMemoryLeaks();

	return 0;
}

Visual Studio 환경에서 F10을 누르면 각 라인 별로 디버깅이 가능합니다.

delete[]를 호출하기 이전의 _CrtDumpMemoryLeaks()에서 메모리 누수(Memory Leak)가 탐지됩니다.

계속 F10으로 메모리를 해제하고 다시 _CrtDumpMemoryLeaks()가 호출되면 아무 것도 표시되지 않습니다.

delete[]로 메모리가 정상적으로 해제되었기 때문입니다.

다만 delete[]를 delete로 변경했을 때는 정상적으로 메모리 누수를 탐지하지 못합니다.

그렇기 때문에 항상 조심해서 코드를 작성해야 합니다.


반응형