- 순서
- 동적할당이란?
- 동적할당시 주의할 점
- 동적할당을 안전하게 하는 법
- 깊은 복사
- 얕은 복사
- 깊은 복사와 얕은 복사의 차이
- 동적할당이란?
- 런타임에 필요한 크기의 메모리를 동적 메모리 영역인 힙에 요청하여 사용하고, 반환하는 방식
- new로 할당하고 delete로 반환하는 형태
- 지역 변수는 스택에 할당되어 호출이 끝나면 자동 소멸하지만, 동적할당은 직업 해제해줘야 하여 스택과 대비됨
- 동적할당시 주의할 점
- 메모리 누수(Leak): 할당한 메모리를 해제하지 않아 누적되어 프로그램 메모리 사용량 증가
- 더블 프리: 같은 포인터를 두 번 delete
- 댕글링 포인터: 해제된 메모리를 참조
- 혼용 사용: new와 free 또는 malloc과 delete와 같이 맞지 않는 요청
- 예외 안전성 미고려: 중간에 예외가 나면 반환이 누락될 수 있음
- 동적할당을 안전하게 하는 법
- C++에서는 직접 new/delete를 쓰지 않는 것이 권장되어, RAII와 스마트 포인터를 사용하는 것이 안전함
- 깊은 복사
- 객체가 소유한 모든 속성을 새로운 메모리 공간에 완전히 복사하여 원본과 독립적인 새로운 객체를 생성하는 방식
- 특징
- 독립적인 새 객체 생성
- 모든 중첩된 데이터 복사
- 원본과 복사본의 완전한 독립성
- 얕은 복사
- 새로운 객체를 생성하지만, 객체 내부의 다른 객체들은 원본 객체의 참조를 그대로 공유하는 복사 방식
- 특징
- 참조 공유: 원본과 복사본이 내부의 객체를 같은 메모리 공간에서 참조함
- 최상위 복사: 객체의 최상위 속성만 새로 복사됨
- 부분적인 독립성: 최상의 속성은 독립적이지만, 중첩된 객체는 독립적이지 않아 원본과 복사본이 동일한 데이터를 공유
- 깊은 복사와 얕은 복사의 차이
| 구분 | 깊은 복사 | 얕은 복사 |
| 복사 방식 | 멤버가 가리키는 자원까지 새로 할당하여 복제 | 멤버 변수의 값 그대로 복사(특히 포인터는 주소만 복사) |
| 포인터 멤버 | 원본과 복사본이 서로 다른 메모리를 가리킴 | 원본과 복사본이 같은 메모리를 가리킴 |
| 독립성 | 원본과 복사본이 독립적 > 서로 영향 없음 | 원본과 복사본이 자원을 공유 |
| 소멸 시 동작 | 각각 독립적으로 자신의 자원을 해제 | 둘 다 같은 자원을 해제하려 해 더블 delete 위험 |
| 속도/비용 | 느림 | 빠름 |
| 기본 동작 | 사용자가 복사 생성자/대입 연산자를 정의해야함 | C++ 컴파일러가 제공하는 기본 복사 생성자/대입 연산자 |
| 문제 발생 가능성 | 성능 저하(복사 비용), 메모리 사용 증가 | 더블 프리, 댕글링 포인터, 예외 안전성 문 |
| 사용 예 | 자원 소유 객체에서 안전한 복제 필요 | 읽기 전용 데이터 공유, shared_ptr 같은 레퍼런스 카운팅 |
'C++' 카테고리의 다른 글
| [C++] 캐스트 연산자/RTTI (0) | 2025.09.03 |
|---|---|
| [C++] malloc/free와 new/delete (0) | 2025.09.03 |
| [C++]포인터와 레퍼런스 (0) | 2025.09.02 |
| [C++]클래스와 구조체 (2) | 2025.09.01 |
| [C++]C와 C++ 언어의 차이점 (1) | 2025.09.01 |