본문 바로가기
언어/C++

[C++ 기본 공부정리] 7. 동적할당(dynamic allocation)

by 민-Zero 2019. 11. 23.

공부 내용을 정리하는 목적 이므로 참고용으로만 읽어 주시기 바랍니다.

틀린 부분에 대한 지적은 감사합니다.

동적할당에 대해 이해하기 위해 메모리의 구조에 대해 알아야 한다. 변수등을 생성하게 되면 메모리에 공간을 할당 받는대 메모리 메모리 영역이 구분되어있고 각 영역마다 하는 역할이 다르다.

메모리는 크게 사용자 영역과 커널 영역이 나뉘어 있다. 

사용자 영역하나의 프로세스에 할당되는 메모리 공간의 일부 영역이며, 프로그램이 동작하기 위해 사용되는 메모리 공간(코드 영역, 데이터 영역, 스택 및 힙 영역)을 가리켜 사용자 영역(User 영역)이다.

커널 영역하나의 프로세스에 할당되는 총 메모리 공간 중에서 유저 영역을 제외한 나머지 영역이며, 운영체제라는 하나의 소프트웨어를 실행시키기 위해서 필요한 메모리 공간을 커널 영역(Kernel 영역)이다.

위와 같은 형태로 간소화 시킬수 있다 이중 동적할당을 위해 User 영역에 대해 알아야 한다.

User 영역은 stack,heap,data,code 크게 4가지로 구분 할 수 있다.

 

-스택(stack) 영역: 함수의 호출과 관계되는 지역 변수와 매개변수가 저장되는 임시적인 영역이다. 함수의 호출과 함께 할당되며, 함수의 호출이 완료되면 소멸한다.

-힙(heap) 영역: 사용자가 직접 관리할 수 있는 메모리 영역이다. 동적으로 메모리를 할당하는 곳이며 생성 중 크기를 결정한다.

-데이터(data) 영역: 프로그램의 전역 변수와 정적(static) 변수, 초기화 된 배열등이 저장되는 영역이다. 데이터 영역은 프로그램의 시작과 함께 할당되며, 프로그램이 종료되면 소멸한다.

-코드(code) 영역: 실행할 프로그램의 명령어나 기계어 명령이 존재 저장되는 영역으로 텍스트(text) 영역이라고도 부른다. CPU는 코드 영역에 저장된 명령어를 하나씩 가져가서 처리하게 된다.

 

1. 동적할당(dynamic allocation)

프로그램이 실행되는 런타임동안 사용자가 직접 공간의 크기나 시점을 결정하여 힙 영역의 메모리를 할당 받는것을 동적할당 이라고 한다. 사용자에 의해 메모리가 동적으로 할당이 되면 프로그램이 끝날 때 까지 유지되므로, 메모리 공간 사용이 끝나면 메모리 낭비(누수)를 줄이기 위해 명시적으로 메모리 할당을 해제 해주어야한다.

 

지금껏 사용하던 지역변수나 매개변수는 정적할당으로 스택영역에 메모리가 할당되어 왔는대 스택영역의 경우 메모리가 작은 크기로 제한되어 있기 때문에 그래픽 같이 용량이 큰 데이터를 저장할 경우 오버플로우의 발생으로 프로그램이 동작하지 않을 가능성이 크다. 따라서 동적할당을 이용하여 운영체제에서 관리하는 좀더 큰 메모리 영역인 힙을 통해 정적할당의 단점을 극복 할 수있다.

 

문법)

타입* 포인터명 = new 타입;

delete 포인터명;

메모리의 동적할당을 실행하는 명령은 new명령어를 사용하며 해제는 delete명령어를 사용한다.

new 로 할당하는 동적할당 타입을 포인터변수 타입과 맞춰 줘야 메모리의 크기를 결정할수 있다. 또한 메모리공간만 할당받아 오는 것이므로 해당 할당받은 공간의 변수명이 존재하지 않으므로 포인터 변수로만 접근 할 수 있다.

 

delete는 동적할당한 포인터변수를 삭제하는 것이 아닌 할당받은 메모리를 운영체제에 다시 돌려주는 것이다. 따라서 delete후에도 포인터 변수는 알수없는 메모리 주소를 가리키고 있게 되며 할당되지 않은 메모리를 참조하면 운영체제가 프로그램을 종료시키게 된다.

 

※주의

동적할당을 통해 할당받은 메모리 주소를 가리키는 포인터를 하나 더 만든후 할당해제를 하여도 포인터 변수는 여전히 할당이 해제된 메모리를 가리키고 있다. 이처럼 할당되지 않은 메모리를 가리키는 포인터를 댕글링 포인터(dangling pointer)라고 한다. 댕글링 포인터를 역참조 하게되면 할당되지 않은 메모리에 임의로 접근할 수 있고 이는 정의되지 않은 동작을 초래한다.

만약 댕글링 포인터를 통해 모든 메모리에 접근 가능하게 하여 컴퓨터의 메모리를 임의로 조작하게 한다면 그 프로그램을 사용하는 사용자는 큰 피해를 입을 가능성이 생긴다. 따라서 댕글링 포인터가 생기지 않도록 주의 해야한다.

댕글링 포인터가 생기지 않게 하려면 여러개의 포인터가 같은 동적 메모리를 가리키게 하지 않도록 해야하며 delete후 동적할당을 실행한 포인터에 0이나 NULL값을 넣는 습관을 들여야 한다.

댓글