소멸자 패턴
Coddy C 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 61개 중 13번째.
malloc으로 생성된 모든 객체는 결국 해제되어야 합니다. 할당을 처리하기 위해 create_ function을 작성했던 것처럼, 정리를 처리하기 위해 free_ function을 작성합니다. 이것이 destructor 패턴입니다.
핵심 통찰은 할당의 역순으로 free가 이루어져야 한다는 것입니다. constructor가 먼저 internal members를 할당한 다음 구조체 자체를 할당했다면, destructor는 먼저 구조체의 members를 free한 다음 구조체를 free해야 합니다:
typedef struct {
char *name;
int age;
} Person;
void free_person(Person *p) {
if (p == NULL) return; // 안전 검사
free(p->name); // 내부 멤버를 먼저 해제
free(p); // 그런 다음 구조체 자체를 해제
}
시작 부분의 NULL 검사는 누군가 실수로 잘못된 포인터를 전달하더라도 충돌을 방지합니다. 내부 name 문자열을 해제한 후 구조체 자체를 해제합니다. 먼저 p를 해제하면 p->name에 접근할 수 없게 되어 메모리 누수가 발생합니다.
소멸자를 사용하는 것은 간단합니다:
Person *alice = create_person("Alice", 30);
// ... alice 사용 ...
free_person(alice); // 완료되면 정리
이 패턴은 모든 memory가 적절히 해제되도록 보장합니다. 이 패턴이 없으면 생성하는 모든 객체에서 memory 누수가 발생하여 프로그램의 memory가 고갈될 때까지 계속됩니다.
챌린지
쉬움완전한 객체 수명 주기, 즉 생성과 소멸을 모두 보여 주는 Movie 모듈을 만들어 봅시다. 할당된 모든 메모리를 올바른 순서로 정리하는 destructor function을 작성하는 연습을 하게 됩니다.
다음 세 파일을 만들게 됩니다.
movie.h: 두 개의 members를 가진Movie구조체를 Declare합니다. members는char *title(동적으로 할당된 문자열)과int year입니다. title과 year를 받는 constructorcreate_movie와 Movie 포인터를 받는 destructorfree_movie를 모두 Declare합니다.MOVIE_H기호를 사용하여 include guard를 설정합니다.movie.c: 두 function을 모두 Implement합니다. constructor는 구조체와 title 문자열을 위한 memory를 Allocate해야 합니다(null 종결자를 잊지 마세요). destructor는 allocation의 역순으로 memory를 Free해야 합니다. 먼저 내부title문자열을 Free한 다음 구조체 자체를 Free합니다. 안전을 위해 destructor의 시작 부분에 NULL check를 포함하세요.main.c: 영화를 Create하고, information을 표시한 다음 memory를 올바르게 정리합니다.
두 개의 입력을 받습니다. movie title(문자열)과 release year(정수)입니다.
main 파일에서 create_movie를 사용하여 새 영화를 Create하고, 해당 information을 출력한 다음 free_movie를 호출하여 모든 memory를 해제하세요. 해제한 후 확인 메시지를 출력합니다.
다음 format으로 출력을 출력하세요.
Movie: {title} ({year})
Memory freed예를 들어 입력이 Inception과 2010이면 출력은 다음과 같습니다.
Movie: Inception (2010)
Memory freed기억하세요. 올바른 destructor의 핵심은 역순으로 Free하는 것입니다. constructor가 먼저 Allocate한 것은 마지막에 Free되고, 마지막에 Allocate한 것은 먼저 Free됩니다.
직접 해보기
#include <stdio.h>
#include <stdlib.h>
#include "movie.h"
int main() {
char title[100];
int year;
// 입력 읽기
scanf("%[^\n]", title);
scanf("%d", &year);
// TODO: create_movie를 사용하여 영화 생성
// TODO: 다음 형식으로 영화 정보 출력:
// Movie: {title} ({year})
// TODO: free_movie를 사용하여 영화 해제
// TODO: "Memory freed" 출력
return 0;
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 C 컴파일러