포인터를 제대로 이해하기: 주소, 역참조, nullptr, 위험한 포인터
3강. 포인터를 제대로 이해하기: 주소, 역참조, nullptr, 위험한 포인터
이번 강의에서 해결할 문제
포인터 문법을 *와 & 기호로만 외우면 null 확인 뒤에도 왜 크래시가 나는지 설명할 수 없습니다. 포인터는 주소를 저장하는 값이고, 역참조가 안전하려면 그 주소에 올바른 타입의 살아 있는 객체가 있어야 합니다.
학습 목표
먼저 알아야 할 핵심 개념
int* pointer는 int 객체의 주소를 담을 수 있는 포인터 변수입니다. &value는 value의 주소를 얻고, *pointer는 그 주소의 객체에 접근합니다. nullptr는 가리키는 대상이 없다는 명시적인 값입니다. 초기화하지 않은 포인터, 파괴된 객체 주소, 배열 범위를 벗어난 주소의 역참조는 UB가 될 수 있습니다.
왜 이 문제가 위험한가
포인터의 비트 값만 보고 대상이 살아 있는지 알 수 없습니다. 삭제 뒤 포인터를 nullptr로 바꾸더라도 같은 주소를 복사해 둔 다른 포인터는 그대로 댕글링입니다. 따라서 “삭제 후 null 대입”보다 누가 소유하고 관찰자는 언제 폐기되는지 설계하는 것이 먼저입니다.
가장 작은 예제로 시작하기
#include <iostream>
void printScore(const int* score) {
if (score == nullptr) {
std::cout << "score unavailable\n";
return;
}
std::cout << "score=" << *score << '\n';
}
int main() {
int score{120};
int* observer{&score};
*observer += 30;
printScore(observer);
printScore(nullptr);
}
score=150
score unavailable
코드 한 줄씩 이해하기
score는 실제 정수 객체이고 값 120을 보관합니다.observer는score의 주소를 복사하지만score를 파괴할 책임은 없습니다.*observer += 30은 주소를 통해 원래score객체를 수정합니다.printScore는 null을 허용한다는 계약을 포인터 타입과 분기로 드러냅니다.- 함수가 실행되는 동안 호출자가
score를 살아 있게 유지하므로 역참조가 유효합니다.
실행 결과와 메모리·동작 흐름
score와 observer는 서로 다른 변수입니다. observer에 저장된 주소를 역참조하면 score 값이 120에서 150으로 바뀝니다. nullptr 호출은 역참조하지 않고 안내 문장을 출력합니다. null 검사는 선택성만 처리하며 수명은 호출자 계약으로 보장합니다.
단계별 실습
흔한 실수와 해결 방법
언제 사용하고 언제 피할까
포인터는 대상이 없을 수 있는 비소유 인자, 연속 메모리의 저수준 API, 기존 C 인터페이스 경계에서 사용합니다. null이 불가능한 필수 대상에는 참조를, 소유권 이전에는 unique_ptr 같은 명시적 타입을 우선합니다.
게임 개발 연결
선택된 대상이 없을 수 있는 시스템은 포인터가 자연스럽지만, 대상을 제거할 수 있다면 관찰자 정리나 안정된 ID 재조회 정책이 함께 필요합니다.
이해 점검 질문 3개
- 포인터 변수와 포인터가 가리키는 객체는 왜 서로 다른 수명을 가질 수 있나요?
nullptr검사가 댕글링 포인터를 찾지 못하는 이유는 무엇인가요?- 필수 수정 인자에 포인터보다 참조가 계약을 더 잘 드러내는 경우는 언제인가요?
핵심 요약
다음 강의 연결
4강. 참조와 포인터 선택 기준에서 함수 API가 필수성, 수정 여부와 소유권을 표현하도록 다듬습니다.
포인터를 제대로 이해하기: 주소, 역참조, nullptr, 위험한 포인터 미니 퀴즈
선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.
학습을 마쳤나요?
직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.