new/delete의 기본 패턴과 해제 후 처리new만 하고 delete를 안 함delete한 객체를 다시 사용(해제 후 사용)delete p; p = nullptr;가 도움이 되는지”를 설명할 수 있다.Monster* m = new Monster();
// ... 사용 ...
delete m;
m = nullptr; // 해제 후에는 바로 무효화(조기 발견에 도움)
핵심 규칙(실전용):
new를 했다면, 같은 책임 범위에서 반드시 delete가 나와야 합니다.delete 뒤에는 포인터를 nullptr로 만들어 “실수로 다시 쓰는 버그”를 빨리 터뜨리는 게 좋습니다.누수의 정체:
전형적인 패턴:
new만 하고 delete를 빼먹음void SpawnMany()
{
for (int i = 0; i < 1'000'000; ++i) {
Monster* m = new Monster();
// ... 어딘가에 저장하지도 않고 ...
// delete m; // ❌ 빠지면 누수
}
}
C# vs C++ 감각:
중요한 착각:
delete p;는 “포인터 변수를 0으로 만드는 명령”이 아닙니다.delete는 “p가 가리키는 대상 객체를 파괴”하는 것이고,그래서 p->hp 같은 접근은:
nullptr로 밀어도 안전하지 않은 이유문제는 “한 포인터만 nullptr로 바꿔서는” 끝나지 않는다는 겁니다.
초기 상태:
m1 ─────► [Monster 객체]
player._target ─► (같은 Monster 객체)
delete m1; m1 = nullptr; 이후:
m1 ─────► nullptr (안전)
player._target ─► [이미 삭제된 자리] (위험: dangling)
즉:
m1 = nullptr;는 m1만 안전하게 만들 뿐,player._target)는 그대로 남아서 Use-After-Free가 됩니다.더 좋은 실전 해법은 이후 Step에서 배우는 스마트 포인터(RAII) 쪽에서 자연스럽게 정리됩니다.
delete p; 다음에 p가 자동으로 nullptr이 되지 않는 이유는?p = nullptr;만으로 충분하지 않은 이유는?