이번 편의 목표: 실행 중에 구조체 메모리를 빌리고, 사용이 끝나면 그 메모리를 돌려줍니다.
배열 선언은 컴파일 때 크기가 정해지는 경우가 많습니다. 권 수가 실행 중에 정해지면 malloc으로 힙에 메모리를 빌립니다. 빌린 주소는 사용이 끝나면 free로 돌려줍니다. 돌려주지 않으면 그 프로세스가 끝날 때까지 재사용할 수 없습니다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Book {
int id;
char title[32];
int price;
};
int main(void) {
struct Book *book = malloc(sizeof(*book));
if (book == NULL) {
printf("메모리를 빌리지 못했습니다.\n");
return 1;
}
book->id = 1;
book->price = 12000;
snprintf(book->title, sizeof(book->title), "%s", "개미");
printf("%s %d\n", book->title, book->price);
free(book);
book = NULL;
return 0;
}sizeof(*book)은 포인터 크기가 아니라 구조체 한 개의 크기입니다. malloc이 실패하면 NULL을 반환하므로 멤버를 쓰기 전에 검사합니다. free 뒤에는 그 주소를 다시 쓰지 않습니다. 변수에 NULL을 넣어 두면 이미 돌려준 주소를 실수로 쓰는 일을 줄일 수 있습니다.
같은 주소를 두 번 free하는 것, free한 뒤의 멤버를 읽는 것은 모두 정의되지 않은 동작입니다. 권 수가 여러 개면 malloc(sizeof(*books) * count)로 배열을 빌리고, free는 그 배열 전체에 한 번만 호출합니다.
직접 해 보기
구조체 두 개 분량을 한 번 malloc하고, 두 권의 제목을 넣은 뒤 출력하고 free하세요.
해설
malloc 인자는 sizeof(*books) * 2입니다. books[0]과 books[1]에 각각 제목을 넣습니다. free(books)는 한 번입니다. 원소마다 free하지 않습니다.
COMMENTS
댓글 0
이 글에 대한 의견이나 질문을 남겨 주세요.
댓글은 구글이나 카카오로 시작한 뒤에 남길 수 있습니다.
등록된 댓글이 없습니다.