C와 C++의 포인터와 주소
이 레슨에서는 변수의 주소를 포인터에 저장하고, 포인터로 값에 접근해 원래 변수를 바꿉니다.
소개
포인터(pointer)는 다른 변수의 메모리 주소를 담는 변수입니다. & 연산자는 변수의 주소를 주고, * 연산자(역참조)는 가리키는 주소에 있는 값에 접근합니다. 포인터는 C와 C++에서 가장 중요한 개념 중 하나입니다.
핵심 정리
- 포인터는 아직 존재하는 올바른 타입의 객체만 가리키거나 null이어야 합니다.
- 할당한 메모리 영역은 정확히 한 번만 해제해야 합니다.
- 어떤 함수가 메모리를 소유(ownership)하는지, 어떤 데이터는 읽기만 하는지(const) 분명히 하세요.
C와 C++ 코드 예제
C
main.c
#include <stdio.h>
int main(void) {
int score = 70;
int *score_ptr = &score;
*score_ptr += 5;
printf("score=%d same-address=%s\n", score,
score_ptr == &score ? "yes" : "no");
return 0;
}
score=75 same-address=yes
C++
main.cpp
#include <iostream>
int main() {
int score = 70;
int* score_ptr = &score;
*score_ptr += 5;
std::cout << "score=" << score << " same-address="
<< std::boolalpha << (score_ptr == &score) << '\n';
}
score=75 same-address=true
C와 C++ 비교
포인터 score_ptr에는 score의 주소가 들어 있으므로, *score_ptr += 5는 실제로 score 변수 자체에 5를 더해 70을 75로 만듭니다. score_ptr == &score 비교로 두 주소가 같다는 것을 확인할 수 있습니다. C++도 메모리 관리 없이 데이터에 접근만 하면 될 때는 원시 포인터(raw pointer)를 쓰지만, 변수가 절대 비어 있으면 안 될 때는 참조를 선호합니다.
C
메모리의 소유와 해제는 전적으로 프로그래머에게 달려 있습니다.
C++
컨테이너와 RAII가 객체의 수명이 끝날 때 자원을 자동으로 해제합니다.
연습 문제
두 버전을 모두 실행한 다음 코드를 바꿔 보면서 각 언어가 주는 안전성의 차이를 살펴보세요.
- 널 포인터와 메모리 할당 실패 상황으로 테스트해 보세요.
- AddressSanitizer와 UndefinedBehaviorSanitizer로 실행해 메모리 오류를 찾아보세요.
- 어떤 포인터가 메모리를 소유하고 어떤 포인터는 읽기만 하는지 분명히 해 보세요.
챌린지로 연습하기
이 레슨에서 배운 내용으로 실제 문제를 풀어 보세요. 모든 챌린지는 브라우저에서 실행되며 즉시 테스트와 AI 리뷰를 받을 수 있습니다.
모든 챌린지