본문 바로가기

개발/C&C++

(C/C++ 속성 정리) 27일 차 : 깊은 복사와 얕은 복사의 이해

안녕하세요 넬다이입니다.

오늘은 정말 오랜만에 이렇게 글을 쓰게 되었습니다. 정말 죄송합니다. ㅠㅠ

 

자 오늘 주제는 깊은 복사와 얕은 복사의 이해입니다. 

이해만 하신다면은 쉬운 주제가 될 것이고 그렇지 못하면은 수많은 버그를 만들 수 도 있기 때문에 잘 이해 부탁드립니다


자 일단 우리는 깊은 복사와 얕은 복사를 알아야 되는데요 깊은 복사와 얕은 복사는 메모리 할당 과정에서

메모리 할당 후 그 내부의 값을 복사하는 과정에서 이 현상이 발생하게 됩니다.

 

얕은 복사

얕은 복사는 메모리 할당을 하고 나서 그 내부의 값을 대입과 같은 행위를 한 뒤 메모리를 해제할 때 문제가 발생하게 됩니다. 예를 들어서 코드로 보여드리겠습니다.

class CObj
{
private :
    char* m_pName;
    
public :
    CObj(char* pName)
    {
    	m_pName = pName
    }
    
    ~CObj()
    {
    	if(m_pName != NULL)
        {
            delete m_pName;
            m_pName = NULL;
        }
    }
}

위 코드에서처럼 분명 m_pName이라는 값이 있고 그 값에 생성자에서 pName을 대입해주는 것을 볼 수 있으며 그 후 소멸자에서 delete m_pName을 해주는 것을 볼 수 있습니다.

이 구문에서는 m_pName이라는 것이 포인터이기 때문에 실제 메모리는 다른 곳에서 생성이 되었을 것이고

그 값이 new를 해서 생성되었는지 아니면 다른 객체가 들고 있는 pName인지 구분이 안되는데 소멸자에서 삭제를 하는 경우를 볼 수 있는데요.

이렇게 되면은 실제 메모리를 가지고 있는 곳에서나 현 소멸자에서든 양쪽 다 delete를 해준다면은 둘 중 어느한곳은 메모리가 삭제가 이미 되어있는 부분이 있을 것입니다.

실제 생성은 한 군데서 하고 삭제는 두 군데서 하는 것과 마찬가지입니다.

 

깊은 복사

깊은 복사는 위와 같은 코드에서 문제가 생기는 것을 방지하기 위해서 메모리를 실제로 생성 후 값을 대입하여 실제 값은 똑같지만 메모리는 다른 메모리를 가지고 있는 형태를 취하는 복사입니다.

class CObj
{
private :
    char* m_pName;
    
public :
    CObj(char* pName)
    {
    	m_pName = new char[strlen(pName) + 1];
        strcpy_s(m_pName , strlen(pName) + 1 , pName);
    }
    
    ~CObj()
    {
    	if(m_pName != NULL)
        {
            delete m_pName;
            m_pName = NULL;
        }
    }
}

위 코드를 보시게 되면은 분명 얕은 복사랑은 다른 코드가 있는데요, 생성자에서 직접 메모리를 생성한 후 값을 복사하는 형태를 취하고 있는 것을 확인하실 수 있으실 것입니다. 

이렇게 코드를 구성하게 되면은 위와 같이 메모리가 서로 다르기 때문에 어느 한 곳에서 메모리 해제 시 터지는 문제를 방지할 수 있으며 이것은 같은 값을 가지고 있을 뿐 실제 다른 메모리인 것을 꼭 인지하셔야 합니다.


마무리

실제 얕은 복사를 사용한 객체는 객체 생성 후 프로그램이 종료되거나 객체의 메모리가 해제될 때 터질 수 있는 위험이 있습니다. 특히 프로그램을 하다 보면은 자주 이런 현상을 발견하게 되는데 얕은 복사를 항상 주의를 해가면서 프로그램을 짜야합니다.

 

[개발/C&C++] - (C/C++ 속성 정리) 26일 차 : Static이란? 및 특징

[개발/C&C++] - (C/C++ 속성 정리) 25일 차 : Const 한정자란?

[개발/C&C++] - (C/C++ 속성 정리) 24일 차 : 객체지향 프로그래밍이란?

[개발/C&C++] - (C/C++ 속성 정리) 23일 차 : 분활컴파일 및

[개발/C&C++] - (C/C++ 속성 정리) 22일 차 : 함수포인터를 이용한 사칙연산 계산기 만들기

[개발/C&C++] - (C/C++ 속성 정리) 21일 차 : 함수포인터