2022. 2. 28. 02:03ㆍIoT Embeded 강의
정적/ 동적 메모리 할당
변수나 배열을 선언하면 각각 메모리에 공간을 차지하게 됩니다. 변수는 자료형에 따라, 배열은 자료형과 크기에 따라 차지하고 있는 공간이 달라지게 됩니다. 정적 메모리 할당은 프로그램 작성 중(Compile time, Design time)에 메모리 공간을 지정하게 되고 프로그램 실행 중(Run time)에는 바꿀 수 없습니다. 이와 달리 포인터와 동적 메모리 할당을 하게 되면 프로그램 실행 중 할당되는 메모리를 사용자의 입력값에 따라 바꿀 수 있게 됩니다.
메모리 할당
포인터 변수가 직접 어떤 변수나 배열의 주소값을 받아 사용될 수도 있지만 포인터에 특정 공간의 메모리를 할당시켜 사용할 수도 있습니다. 이를 하기 위해선 먼저 <malloc.h>헤더파일을 삽입해줘야 합니다. 이 후 메모리 할당 함수들을 사용할 수 있게 되는데 malloc, calloc, realloc, free 함수에 대해 설명하겠습니다.
1
2
3
4
5
6
7
8
|
#include <stdio.h>
#include <malloc.h> int main() { int* ptr1 = (int*)malloc(sizeof(int) * 10); int* ptr2 = (int*)calloc(10,sizeof(int)); int* ptr2 = (int*)realloc(ptr2, sizeof(int) * 20); free(ptr1); free(ptr2); return 0; } |
cs |
malloc(byte단위의 메모리 크기)
malloc 함수는 byte단위의 메모리 크기를 매개 변수로 받습니다. 할당하고 싶은 메모리 공간의 크기를 인자로 입력해주면 됩니다. 위의 코드에서는 sizeof(int)*10 = 4byte * 10 = 40byte 로 입력했습니다. sizeof 연산자를 사용하여 int형의 메모리 크기를 표현한 이유는 다른 프로그램에서는 int형의 메모리 크기가 4byte라는 보장이 없기 때문입니다. malloc함수가 인자를 받아 반환하는 값은 포인터, 주소값입니다. 위의 3번줄에서 int형 ptr 포인터 변수에 주소값이 들어가는 것입니다. 이 때 (int*)로 캐스트 연산자를 써줍니다. 왜냐하면 malloc함수의 반환값은 자료형이 void*형이기 때문입니다. 포인터에서 void*형은 아직 자료형이 정해져 있지 않은 상태를 의미합니다. 만일 ptr1을 void*형으로 선언한다면 어떤 자료형의 변수나 배열에서 캐스트 연산자만 붙여주면 사용 가능합니다. 다만 조금 번거로울 뿐입니다. malloc함수도 포인터를 반환하고 void*형이기 때문에 자료형을 맞춰주기 위해 타입변환을 해줍니다.
결과적으로 ptr1 포인터 변수에는 40byte의 메모리 공간의 첫번째 주소가 대입됩니다. 40byte의 모든 주소가 들어가는 것이 아닌 첫번째 주소가 들어가는 것을 기억해야 합니다.
calloc(데이터 개수, 데이터 1개의 크기)
malloc 함수가 이해가 됐다면 calloc는 쉽습니다. 매개 변수는 '데이터 개수', '데이터 1개의 크기' 로 받습니다. 위의 코드도 결과적으로 40byte의 메모리 공간을 할당하는 것입니다. 또 하나의 차이점은 calloc함수는 할당되는 메모리 공간 안의 데이터들을 모두 '0'으로 초기화까지 해줍니다. malloc함수로 메모리할당만 하면 그 안에는 가비지 값이 들어 있습니다.
realloc(포인터 변수, byte단위 메모리 크기)
메모리를 할당 받아 쓰다보면 공간이 모자란 경우가 발생합니다. 이 때 메모리 할당을 늘려주는 함수입니다. 메모리 공간을 늘리고 싶은 포인터 변수와 늘리려는 메모리 크기가 매개 변수입니다 . 유의할 점은 기존 메모리 공간의 바로 뒤에 여유 공간이 있을 경우 그 공간에 연결해서 늘려주고, 그렇지 않다면 여유가 있는 새로운 공간에 메모리를 할당하고 기존의 데이터들을 모두 복사해 옮겨줍니다. 따라서 기존의 포인터(주소)가 변경될수도 있습니다.
위의 세 함수 모두 메모리에 할당할 수 있는 공간이 없을 때 NULL값을 반환합니다.
free(포인터 변수)
free함수는 인자로 받는 포인터 변수가 받은 메모리를 반납하게 합니다. 메모리를 할당한 뒤에는 이처럼 free함수로 무조건 반납해줘야 합니다. 그렇지 않으면 점차 사용할 수 있는 메모리 공간이 줄어듭니다. 이를 메모리 누수(Memory leakge)라고 합니다.
메모리 할당 함수의 인자에 변수를 넣을 수 있습니다. 때문에 프로그램 실행 후 사용자로부터 값을 입력받아 메모리 할당 크기를 설정할 수 있습니다. 때문에 포인터는 배열보다 메모리 가변성이 우수합니다.
'IoT Embeded 강의' 카테고리의 다른 글
2022.03.01 구조체 (0) | 2022.03.01 |
---|---|
2022.02.28 유틸리티 함수, 수학 함수 (0) | 2022.03.01 |
포인터 / 포인터 선언 / 초기화 / 연산 / 문자열 (0) | 2022.02.28 |
자료형과 해석 (0) | 2022.02.24 |
배열과 문자열 (0) | 2022.02.14 |