동적 할당의 문제: new·delete, 메모리 누수, 이중 해제
5강. 동적 할당의 문제: new·delete, 메모리 누수, 이중 해제
이번 강의에서 해결할 문제
new로 만든 객체는 정상 경로뿐 아니라 조기 반환과 예외 경로에서도 정확히 한 번 정리되어야 합니다. 코드가 커질수록 수동 delete를 모든 경로에 맞추기 어렵고, 복사된 주소 때문에 누수나 이중 해제가 생깁니다.
학습 목표
먼저 알아야 할 핵심 개념
new T는 동적 저장 기간의 T 객체를 만들고 주소를 반환합니다. 대응하는 delete는 객체의 소멸자를 호출하고 저장소를 반납합니다. 배열 new[]에는 delete[]가 필요하지만, 현대 C++ 애플리케이션에서는 직접 맞추기보다 vector, string, unique_ptr 같은 RAII 타입을 우선합니다.
왜 이 문제가 위험한가
다음 위험 코드는 실행하지 않아도 제어 흐름만으로 문제를 찾을 수 있습니다.
Task* loadTask(bool valid) {
Task* task = new Task{"build", 2};
if (!valid) return nullptr; // task를 잃어버려 누수
return task; // 누가 delete할지 시그니처에 없음
}
void doubleOwner(Task* task) {
Task* alias = task;
delete task;
delete alias; // 같은 객체를 두 번 정리: UB
}
nullptr로 바꾸는 습관만으로는 복사된 alias를 고칠 수 없습니다. 소유자가 정확히 한 곳이 되도록 타입과 구조를 바꿔야 합니다.
가장 작은 예제로 시작하기
#include <iostream>
#include <memory>
#include <string>
#include <utility>
struct Task {
std::string name;
int priority{};
};
std::unique_ptr<Task> makeTask(std::string name, int priority) {
if (name.empty() || priority < 0) return nullptr;
return std::make_unique<Task>(Task{std::move(name), priority});
}
int main() {
auto task = makeTask("build", 2);
if (task) std::cout << task->name << ':' << task->priority << '\n';
}
코드 한 줄씩 이해하기
- 반환 타입
unique_ptr<Task>가 성공 시 단일 소유권이 호출자로 이동함을 나타냅니다. - 유효하지 않은 입력은 객체를 만들기 전에
nullptr결과로 종료합니다. make_unique는 생성과 소유 포인터 구성을 한 표현으로 묶습니다.task가main을 벗어나면Task가 정확히 한 번 파괴됩니다.- 수동
delete가 없어 조기 반환 경로도 같은 정리 규칙을 따릅니다.
실행 결과와 메모리·동작 흐름
유효한 입력에서는 Task가 동적으로 생성되고 main의 task가 유일한 소유자가 됩니다. build:2를 출력한 뒤 스코프 종료 시 자동 정리됩니다. 빈 이름이면 동적 객체 자체가 만들어지지 않습니다.
단계별 실습
흔한 실수와 해결 방법
언제 사용하고 언제 피할까
런타임에 구체 타입이 정해지는 다형 객체나 명시적인 독립 수명이 필요하면 RAII 기반 동적 소유를 사용합니다. 크기와 수명이 명확한 값, 컨테이너가 직접 보관할 수 있는 객체에는 수동 동적 할당을 피합니다.
게임 개발 연결
많은 객체를 반복 생성하는 코드에서 누수는 시간이 지날수록 커집니다. 먼저 객체를 값으로 둘 수 있는지 검토하고, 동적 수명이 필요할 때만 소유자를 한 곳으로 정합니다.
이해 점검 질문 3개
- raw pointer 반환이 삭제 책임을 명확히 전달하지 못하는 이유는 무엇인가요?
- 조기 반환이 수동
new코드에서 누수를 만들기 쉬운 이유는 무엇인가요? - 동적 할당 대신
vector<Task>값 저장이 더 적합한 사례는 무엇인가요?
핵심 요약
다음 강의 연결
6강. RAII에서 메모리뿐 아니라 파일과 잠금 자원도 객체 수명으로 정리합니다.
동적 할당의 문제: new·delete, 메모리 누수, 이중 해제 미니 퀴즈
선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.
학습을 마쳤나요?
직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.