C++/C++ 기본

동적 메모리 할당 및 반환

검정비니 2018. 7. 16. 18:33
728x90
반응형

동적 메모리 할당 및 반환



1. 동적 메모리 할당


일반적으로 개발자는 프로그램 작성 단계에서 필요한 메모리를 확보하기 위해 변수, 객체, 배열을 정적으로 선언한다. 하지만, 문서 편집기나 그래픽 편집기를 개발하는 경우, 몇 줄의 텍스트를 입력할 것인지, 몇 개의 도형을 그릴 것인지 사용자의 마음에 달려 있기 때문에, 필요한 메모리를 프로그램을 작성하는 단계에서 모두 선언을 하는 것은 불가능하다고 할 수 있다. 물론, 크기가 작은 프로그램의  경우 가능할 수는 있겠지만, 프로그래머가 언제나 크기가 작은 프로그램만 만들지는 않을 뿐더러, C 프로그래밍을 해본 사람들은 알겠지만 포인터를 사용하다보면 동적 할당이 반드시 필요한 상황들이 생기고는 한다. 그렇기에, C++에서는 동적으로 메모리를 할당하고, 다 쓰고나면 반환을 하는 '메모리 할당/반환' 방식을 제공한다.


C언어에서는 동적 메모리 할당을 위해 malloc() 함수를, 메모리 반환을 위해 free() 함수를 이용한다. 이는 C 언어에서의 표준 함수이지 C++에서의 표준 함수가 아니다. C++에서는 new 연산자와 delete 연산자를 이용한다. new 연산자는 힙(heap)이라는 시스템 공간으로부터 메모리를 할당받고, delete 연산자는 할당받은 메모리를 힙으로 반환한다.



2. new와 delete 연산자


new 연산자와 delete 연산자는 C++의 기본 연산자이다.


- new와 delete의 기본 활용


new와 delete 연산자의 기본 형식은 다음과 같다.


데이터_타입 *포인터_변수 = new 데이터_타입;

delete 포인터 변수;


new 연산자는 사용하려는 데이터 타입의 크기만큼 힙으로부터 메모리를 할당받고 주소를 리턴한다. 그 결과, '포인터 변수'는 할당받은 메모리의 주소를 가진다. delete 연산자는 '포인터 변수'가 가리키는 메모리를 힙으로 반환한다. '데이터 타입'은 int, char, double 등 기본 타입뿐 아니라 구조체(struct), 클래스(class)도 포함된다.


힙 메모리가 부족하면 new 연산자는 NULL을 리턴하므로, new의 리턴 값이 NULL인지 검사하는 것이 좋다.


i.e.

int *p = new int;

if (!p) { // if( p== NULL) 과 동일.

return;

}

*p = 5; //포인터가 가리키는 주소에 정수 5를 넣는다.

int n = *p; //포인터 p가 가리키는 주소에 저장된 값을 변수 n에 저장

delete p; //p에 할당된 메모리 반환



- 동적 할당 메모리 초기화


new를 이용하여 메모리를 할당받을 때, 다음과 같이 '초깃값'을 지정하여 초기화할 수 있다.


데이터_타입 *포인터_변수 = new 데이터_타입(초깃값);


다음 예시를 통해서 더 자세히 알아보도록 하자.


i.e.

int *pInt = new int(20); //20으로 초기화된 int 공간 할당

char *pChar = new char('a'); //'a'로 초기화된 char 공간 할당



- delete 사용 시 주의


delete로 메모리를 반환할 때 적절하지 못할 포인터를 사용하면, 실행 오류가 발생한다. 또한, 동일한 메모리를 두 번 반환하면 실행 오류가 발생한다.





3. 배열의 동적 할당 및 반환



new와 delete 연산자로 배열을 할당받고 반환할 수 있다.


- 배열의 동적 할당/반환의 기본 형식


배열을 동적으로 할당받고 반환하는 경우에도 new 연산자와 delete 연산자를 사용한다. 그 기본 형식은 다음과 같다.


데이터_타입 *포인터_변수 = new 데이터_타입 [배열의_크기]; //배열의 동적 할당

delete [] 포인터_변수; //배열 메모리 반환


new 연산자는 '배열의 총 메모리 크기'에 해당하는 메모리를 할당 받아서 그 메모리의 시작 주소를 반환한다. delete는 '포인터_변수'가 가리키는 배열 메모리를 반환한다. new 연산자를 통해서 char, int 와 같은 기본 타입의 배열 뿐 아니라 구조체, 클래스 등 사용자가 정의한 타입의 배열도 할당 받을 수 있다.


- 배열을 초기화할 때 주의 사항


기본 형식에서의 메모리 할당과는 달리, new로 배열을 동적 할당받을 때 '초깃값'을 지정할 수 없다.

다음 예시는 new 연산자의 오용으로 인해서 컴파일 오류가 발생하는 경우이다.


i.e.

int *pArray = new int[10] (20); //구문 오류. 배열의 초기화는 불가능하다.

int *pArray = new int(20) [10]; //구문 오류.


- 배열을 delete할 때 주의 사항


배열을 반환할 때 delete 연산자에 []를 생략하면, 컴파일 오류는 발생하지 않지만 비정상적인 반환이 되므로 주의해야 한다.


i.e.

int *p = new int[10];

delete p; //비정상 반환. delete [] p;로 하여야 한다.

int *q = new int;

delete [] q; //비정상 반환. delete q;로 하여야 한다.

반응형

'C++ > C++ 기본' 카테고리의 다른 글

this 포인터  (0) 2018.07.17
객체와 객체 배열의 동적 생성 및 반환  (0) 2018.07.17
다차원 객체 배열  (0) 2018.07.07
객체 배열  (0) 2018.07.07
객체 포인터  (2) 2018.07.07