Menu
Coddy logo textTech

깊은 복사

Coddy C 여정의 Object Oriented Programming 섹션에 포함된 레슨 — 61개 중 15번째.

C 언어에서 하나의 구조체(struct)를 다른 구조체에 대입할 때, 얕은 복사(shallow copy)가 수행됩니다. 즉, 모든 필드가 바이트 단위로 복사됩니다. 이는 정수와 같은 단순한 값에는 잘 작동하지만, 포인터의 경우에는 문제가 발생합니다. 두 구조체가 결국 동일한 메모리를 가리키게 되기 때문입니다.

typedef struct {
    char *name;
    int age;
} Person;

Person alice = {"Alice", 30};
Person copy = alice;  // 얕은 복사!
// alice.name과 copy.name 모두 동일한 문자열을 가리킵니다

하나를 해제하면 다른 하나는 유효하지 않게 됩니다. 하나를 통해 문자열을 수정하면 두 곳 모두에 변경 사항이 반영됩니다. 이는 대개 여러분이 원하는 결과가 아닙니다.

깊은 복사(deep copy)는 포인터 멤버를 위해 새로운 메모리를 할당하고 실제 데이터를 복사합니다:

Person *clone_person(const Person *original) {
    Person *copy = malloc(sizeof(Person));
    copy->name = malloc(strlen(original->name) + 1);
    strcpy(copy->name, original->name);
    copy->age = original->age;
    return copy;
}

이제 각 객체는 고유한 문자열을 소유합니다. 다른 객체에 영향을 주지 않고 하나를 수정하거나 해제할 수 있습니다. 이 패턴은 명확합니다. 각 포인터 멤버에 대해 새로운 메모리를 할당하고, 단순히 주소만 복사하는 것이 아니라 내용을 복사하는 것입니다.

challenge icon

챌린지

쉬움

딥 카피(deep copy) 패턴을 보여주는 Student 모듈을 만들어 보겠습니다. 원본을 수정하거나 해제해도 복제본에 아무런 영향을 주지 않는, 완전히 독립적인 학생 객체 복사본을 생성하는 클로닝 함수를 만들 것입니다.

세 개의 파일을 생성하게 됩니다:

  • student.h: 두 개의 멤버를 가진 Student 구조체를 선언합니다: char *name (동적으로 할당된 문자열)과 int grade. 다음 세 가지 함수를 선언합니다:
    • create_student — 이름과 성적을 받아 새로운 Student에 대한 포인터를 반환하는 생성자
    • clone_studentconst Student *를 받아 새롭고 독립적인 복사본에 대한 포인터를 반환하는 함수
    • free_student — 할당된 모든 메모리를 적절히 해제하는 소멸자
    STUDENT_H 심볼을 사용하여 인클루드 가드(include guards)를 적용하세요.
  • student.c: 세 가지 함수를 모두 구현합니다. clone_student 함수가 핵심입니다. 이 함수는 구조체와 이름 문자열 모두를 위해 새로운 메모리를 할당한 다음, 실제 문자열 데이터(포인터 주소만이 아닌)를 복사해야 합니다. 이를 통해 복제본이 원본과 완전히 분리된 자체 메모리를 소유하도록 보장합니다.
  • main.c: 학생을 생성하고, 이를 복제하고, 두 학생의 정보를 표시한 다음, 두 객체를 모두 적절히 정리합니다.

두 개의 입력을 받게 됩니다: 학생 이름 (문자열)과 성적 (정수).

메인 파일에서 제공된 값으로 학생을 생성한 다음, 해당 학생의 복제본을 만듭니다. 원본과 복제본의 정보를 모두 출력하여 동일한 데이터를 포함하고 있는지 확인하세요. 마지막으로 두 학생을 모두 해제하고 확인 메시지를 출력합니다.

출력은 다음 형식으로 하세요:

Original: {name}, Grade: {grade}
Clone: {name}, Grade: {grade}
Both freed

예를 들어, 입력값이 Alice95인 경우 출력은 다음과 같습니다:

Original: Alice, Grade: 95
Clone: Alice, Grade: 95
Both freed

딥 카피 패턴은 각 객체가 진정으로 독립적임을 보장합니다. 즉, 복제본은 원본 메모리에 대한 공유 포인터가 아니라 자신만의 할당된 문자열을 가집니다.

직접 해보기

#include <stdio.h>
#include <stdlib.h>
#include "student.h"

int main() {
    char name[100];
    int grade;
    
    // 입력 읽기
    scanf("%s", name);
    scanf("%d", &grade);
    
    // TODO: 제공된 name과 grade를 사용하여 student 생성
    
    // TODO: student의 복제본(clone) 생성
    
    // TODO: 원본 student의 정보 출력
    // 형식: "Original: {name}, Grade: {grade}"
    
    // TODO: 복제본(clone)의 정보 출력
    // 형식: "Clone: {name}, Grade: {grade}"
    
    // TODO: 두 student 모두 메모리 해제(Free)
    
    // 확인 메시지 출력
    printf("Both freed\n");
    
    return 0;
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

Object Oriented Programming의 모든 레슨