메모리 할당 방식
정적 : 프로그램 실행 전 변수의 저장공간을 먼저 할당 후 프로그램 종료시 해제
동적 : 프로그램 실행 중 필요한만큼 메모리 할당 후 원할 때 해제
c 언어의 표준 라이브러리로 stdlib.h에 정의되어 있다.
void *malloc(size_t size);
인자로 전달된 정수 값에 해당하는 바이트 크기의 메모리 공간을 힙 영역에 할당하고, 이 메모리 공간의 주소값을 반환한다. 즉, size_t 만큼의 크기만큼 메모리를 할당하고 성공하면 할당한 메모리의 시작 주소를 리턴하고 실패시 NULL을 리턴한다.
왜 void* 를 반환할까?
동적으로 메모리 할당을 하는데 정수를 저장할지, 배열을 저장할지, 구조체를 저장할지 실질적으로 모르기 때문이다.
왜 동적 메모리 할당을 해야하는가?
정적 메모리를 할당하게 되면, 기억공간이 낭비될 경우가 많다. 메모리 낭비를 최소화하기 위해서는 프로그램의 실행 중 입력되는 데이터에 맞게 기억 공간을 할당할 필요가 있다.
프로그램을 실행하게 되면 OS는 RAM(memory)에 공간을 할당해준다.
이때 할당해주는 메모리 공간은 4가지(Code, Data, Stack, Heap)가 있다.
우리가 작성한 Source code가 들어가는 부분이다. 즉, 실행할 프로그램의 코드가 저장되는 영역으로 텍스트 영역 이라고도 부른다.
코드 영역은 실행 파일을 구성하는 명령어들이 올라가는 메모리 영역으로 함수, 제어문, 상수 등이 여기에 지정된다.
전역변수와static 변수가 할당되는 영역으로 프로그램의 시작과 동시에 할당되고, 프로그램이 종료되어야 메모리가 소멸되는 영역이다.
import Foundation #define BUF = 10; // 데이터 영역에 할당 #define BUF = 20; // 데이터 영역에 할당 func dataFunc() -> Bool { return true }
프로그램이 자동으로 사용하는 임시 메모리 영역이다.
함수 호출 시 생성되는 지역 변수와 매개변수가 저장되는 영역으로,함수 호출이 완료되면 사라진다. 이렇게 스택(Stack) 영역에 저장되는 함수의 호출 정보를 Stack Frame이라고 한다.
Stack 영역에 데이터는 어떻게 해제되나?
스택(Stack)영역의 데이터는 자동변수 영역으로 함수가 리턴될 때 자동으로 메모리가 회수된다. 스택(Stack)은 함수가 새 변수를 선언할 때 마다 푸시(push)로 데이터를 저장하고 함수가 종료될 때 마다 팝(pop)으로 데이터를 인출, 즉 모든 변수를 해제(삭제)한다. 이러한 스택은후입선출(LIFO) 방식에 따라 동작하므로, 가장 늦게 저장된 데이터가 가장 먼저 인출된다.
import Foundation #define BUF = 10; // 데이터 영역에 할당 #define BUF = 20; // 데이터 영역에 할당 func dataFunc() -> Bool { someFunc1(3) someFunc2(5) return true } func someFunc1(c: Int) { int d = 30; // 매개변수 c와 지역변수 d가 스택영역에 할당 } void someFunc2(e: Int) { int f = 40; // 매개변수 e와 지역변수 f가 스택영역에 할당 }
사용자가 할당/해제하는 메모리 공간이다. Java에서는 가비지 컬렉터가 자동으로 해제한다. 이 공간에 메모리 할당하는 것을 Dynamic Memory Allocation이라고 부른다. 힙(Heap) 영역에 작성된 변수는 프로그램의 모든 함수에서 액세스할 수 있다. 힙(Heap) 변수는 본질적으로 범위가 전역 이다.
힙(Heap) 영역의 메모리를 해제하지 않으면 어떻게 되나?
힙(Heap) 영역의 메모리를 회수하지 않으면 프로그램이 실행이 되는 동안 무한정 쌓이게 되고 이는 상당한 메모리 낭비, 메모리 누수가 발생한다.
스택(Stack) 과 힙(Heap)의 차이
스택은 정적 메모리 구조를 가지고 힙 영역은 동적 메모리 구조를 가진다
메모리를 할당 받고 메모리가 해제되지 않으면 할당받은 메모리는 사용이 끝났음에도 불구하고 컴퓨터가 종료되기 전까지 해당 메모리를 차지하게 된다.
메모리를 할당만하고 해제를 안하면 어떻게 될까?
메모리 부족 현상, 메모리 누수가 발생한다. 따라서 동적할당 후 더 사용할 필요가 없다면 메모리 해제를 시켜주어야 한다.
free 함수는 동적으로 할당된 메모리를 해제하는 함수이다.
void free(void *ptr);
동적으로 할당한 메모리는 부분적으로 해제할 수 없다. 따라서 프로그램에서는 동적으로 할당한 메모리 주소를 기억해 두었다가 더 이상 사용하지 않을 때 free 함수로 해제합니다.