Notice
Recent Posts
Recent Comments
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Archives
Today
Total
관리 메뉴

SYDev

C++ Chapter 05-2 : '깊은 복사'와 '얕은 복사' 본문

Programming Lang/C++

C++ Chapter 05-2 : '깊은 복사'와 '얕은 복사'

시데브 2023. 7. 17. 14:49

디폴트 복사 생성자의 문제점

 디폴트 복사 생성자는 멤버 대 멤버 복사를 진행한다. 그리고 이러한 복사 방식을 가리켜 '얕은 복사(shallow copy)'라고 하는데, 이 경우 멤버변수가 힙의 메모리 공간을 참조하는 경우에 문제가 된다. 

 

 다음 예제를 통해서 문제점을 확인해보자. 해당 예제는 생성자와 소멸자 파트에서 나왔던 Destructor.cpp의 main함수를 조금 수정한 것이다.

#include <iostream>
#include <cstring>
using namespace std;

class Person
{
private:
    char * name;
    int age;
public:
    Person(char *myname, int myage)
    {
        int len=strlen(myname)+1;
        name=new char[len];
        strcpy(name, myname);
        age = myage;
    }

    void ShowPersonInfo() const
    {
        cout<<"이름 : "<<name<<endl;
        cout<<"나이 : "<<age<<endl;
    }
    ~Person()
    {
        delete []name;
        cout<<"called destructor!"<<endl;
    }
};

int main(void)
{
    Person man1("Lee dong woo", 29);
    Person man2 = man1;
    man1.ShowPersonInfo();
    man2.ShowPersonInfo();

    return 0;
}
이름 : Lee dong woo
나이 : 29
이름 : Lee dong woo
나이 : 29
called destructor!

 위 코드의 실행 결과의 문제점은 바로 called destructor가 한 번 출력되었다는 것이다. 이는 소멸자가 한 번만 실행되었다는 것을 의미한다. 정상적인 상황이라면 두 개의 객체를 생성했기 때문에 소멸자는 두 번 호출되어야 하는데 한 번만 호출된 것이다. 무슨 문제가 발생한 것일까?

 

 디폴트 복사 생성자는 단순히 멤버 대 멤버 복사만 진행하기 때문에, 두 생성자의 멤버들이 같은 메모리 공간을 참조하게 된다. 그렇기 때문에 소멸자가 한 번만 실행 되면 두 멤버에게 할당된 공용 메모리 공간이 소멸되기 때문에 다음 소멸자가 호출되면 소멸시킬 메모리 공간이 없는 상태가 되는 것이다. 이미 지워져버린 공간을 대상으로 delete 연산을 진행하는 것은 문제가 된다. 그렇기 때문에 복사 생성자를 사용할 때에는 이런 문제를 신경써야 한다. 

얕은 복사
깊은 복사
man2 객체 소멸

 깊은 복사(deep copy)

 우리는 이와 같은 문제를 해결하기 위해서 위의 두 번째 그림 형태로 복사를 진행해야 한다. 해당 복사의 형태를 '깊은 복사(deep copy)'라고 부르며, 포인터로 참조하는 대상까지 복사한다는 뜻을 가지고 있다.

 

 깊은 복사를 구현하기 위해서 아래와 같은 간단한 복사 생성자 하나만 추가해주면 된다.

Person(const Person &copy) : age(copy.age)
    { 
        name = new char[strlen(copy.name)+1];
        strcpy(name, copy.name);
    }

 


출처 : 윤성우, <윤성우의 열혈 C++ 프로그래밍>, 오렌지미디어, 2010.05.12