티스토리 뷰
2021.03.04.목
malloc, free 함수
✔ malloc() 함수를 사용해서 동적 메모리를 할당받고, free() 함수를 사용해서 반환한다.
✔ malloc() 함수와 free() 함수는 <stdlib.h> 헤더 파일에 포함되어 있으니 전처리가 필요하다.
(포인터 형변환) malloc (메모리크기);
int * p = (int *) malloc (sizeof(int));
✔ malloc() 함수는 void 포인터를 반환하므로, 포인터 변수에 저장할 때에는 필요한 자료형으로 형변환해야한다.
✔ 필요한 만큼 공간을 할당받을 수 있는데, 이는 byte기준이며, sizeof() 연산자를 사용해 크기를 계산해 넣어주자.
✔ 그렇게 하면 컴파일러나 운영체제에 따라 int형 변수의 크기가 다르더라도 수정할 필요가 없다.
int *p = (int*)malloc(sizeof(int)*10);
if(p==NULL
printf("동적 메모리 할당 실패\n");
return 1;
}
✔ 메모리 공간이 부족하여 동적 메모리를 할당하지 못하면, malloc() 함수는 0(null)을 반환한다.
✔ if문을 사용해 위와 같이 반환 값을 검사하여 메모리 공간이 부족한 상황을 대비하자.
int * p = (int *) malloc (sizeof(int));
free(p);
✔ malloc() 함수를 사용해 할당받은 메모리 공간은 사용이 끝나면 반드시 반환해야 한다.
✔ 지역 변수에게 할당된 메모리 공간은 함수가 종료될 때 자동 반환되지만 동적 메모리 공간은 그대로 남아있다.
✔ 따라서 함수가 반환되기 전에, 동작 할당받은 공간은 free() 함수로 직접 반환해야 한다.
동적 할당 영역을 배열처럼 쓰기
int * pa = (int *) malloc (sizeof(int)*10);
✔ 형태가 같은 변수가 많이 필요하다면, 한 번에 많은 저장 공간을 할당하여 배열처럼 사용할 수 있다.
✔ 위와 같이 int형 변수 10개를 저장할 수 있는 동적 메모리를 할당받아
✔ 포인터 변수 pa에 저장하면 배열처럼 사용할 수 있다.
#include <stdio.h>
#include <stdlib.h>
int main(void){
int sum = 0;
int *pa = (int*)malloc(sizeof(int)*5);
for(int i=0; i<5; i++){
scanf("%d", pa+i);
sum+=pa[i];
}
printf("합은 %d",sum);
free(pa);
return 0;
}
기타 동적 할당 함수
✔ 동적 메모리를 할당받을 때 가장 많이 사용하는 함수는 malloc()이지만, 다른 함수도 존재한다.
// calloc 함수 원형
void *calloc(unsigned int, unsigned int);
// calloc 함수 사용 예제
int * p;
p = (int*)malloc(sizeof(int)*10);
p = (int*)calloc(10, sizeof(int));
✔ calloc() 함수는 동적 메모리 공간을 할당 받음과 동시에 0으로 초기화한다.
✔ malloc() 함수는 int형 변수 10개를 저장할 수 있는 동적 메모리를 할당받을 때 sizof(int)*10이라고 입력하는데
✔ calloc() 함수는 첫 번째 인수로 필요한 공간의 개수 10을 전달하고, int형의 크기를 두 번째 인수로 전달한다.
// realloc 함수 원형
void *realloc(void *, unsigned int);
// realloc 함수 사용 예제
int * p;
p = (int*)malloc(sizeof(int)*10);
p = (int*)realloc(p, sizeof(int)*20);
✔ realloc() 함수는 이미 할당받은 메모리 공간의 크기를 조절한다.
✔ malloc() 함수를 사용해 int형 크기의 10개 공간을 처음에 할당받았는데
✔ realloc() 함수를 사용해 int형 크기의 20개 공간으로 다시 메모리 공간의 크기를 조절했다.
✔ 메모리 공간 크기를 늘리는 경우는 상관없지만, 줄이는 경우에는 데이터 소실이 있을 수 있으니 주의하자.
#include <stdio.h>
#include <stdlib.h>
int main(void){
int size = 5;
int * pi = (int*)calloc(size, sizeof(int));
int cnt = 0;
int num;
printf("> 입력을 멈추고 싶다면 -1을 입력하세요\n");
while(1){
scanf("%d", &num);
if(num==-1) break;
//반복 횟수를 통해 남은 저장 공간을 확인하고
//남은 저장 공간이 없으면 size를 +5해주고 동적 메모리 공간 재 할당.
if(cnt==size){
size+=5;
pi = (int*)realloc(pi, sizeof(int)*size);
}
pi[cnt]=num;
cnt++;
}
for(int i=0; i<size; i++){
printf("%5d", pi[i]);
if((i+1)%5==0) printf("\n");
}
free(pi);
return 0;
}
✔ realloc() 함수는 인자를 통해서 크기를 변경할 포인터를 받는데, 왜 다시 대입해줘야 할까?
✔ 크기를 늘리는 경우, 연속적인 메모리공간 할당이 불가능할 때 해당 동적 메모리는 해제하고
✔ 새로운 주소의 동적 메모리를 할당한다. 그래서 다시 포인터변수에 주소를 대입해주어야만 한다.
[참고] 한빛미디어-혼자 공부하는 C언어 유튜브 강의 / 엘리스 트랙-혼자 공부하는 C언어 / 길벗-C언어 코딩 도장 / 위키백과
'BackEnd > C' 카테고리의 다른 글
[22일차] 1. 구조체와 멤버 (0) | 2021.03.05 |
---|---|
[21일차] 2. 동적 할당의 활용 / 명령행 인수 (0) | 2021.03.04 |
[20일차] 5. 함수 포인터/void 포인터 (0) | 2021.03.03 |
[20일차] 4. 2차원 배열과 배열 포인터 (0) | 2021.03.03 |
[20일차] 3. 배열 요소의 주소와 배열의 주소 (0) | 2021.03.03 |