
Python이나 JavaScript로 시작했다면 포인터는 흰 수염의 시스템 엔지니어만 쓰는 신비한 마법처럼 들린다. 대학에서 C++를 배웠다면 세그멘테이션 폴트와 메모리 누수에 고생한 기억이 있다.
비밀은 이렇다. 포인터는 그냥 변수다. 그 값은 숫자다. 그 숫자는 다른 무언가의 주소를 담고 있다.
포인터를 이해하려면 먼저 데이터가 어디에 사는지 알아야 한다.
코드가 실행되면 데이터는 어딘가에 놓여야 한다. 그 자리는 스택 아니면 힙이다.
스택은 책상 위의 포스트잇 더미를 떠올리면 된다.
int a = 10; 같은 변수가 있다면 보통 여기에 놓인다. 빠르고 안전하다.
힙은 거대한 창고다.
포인터는 단순히 이정표다.
score = 99 라는 변수가 힙(주소 0x1234)에 있다고 하자. 포인터는 스택 위의 아주 작은 변수로, "데이터는 0x1234에 있다"고 알려준다.
int score = 99; // 실제 값
int *p = &score; // 포인터 'p'는 'score'의 주소를 담고 있음p는 주소다. 데이터가 어디 있는지를 말한다. *p는 값, 곧 그 주소에 담긴 것이다.
그냥 값을 전달하고 언어가 뒤처리를 하게 두면 안 되나?
10MB 이미지를 떠올려 보자. 그것을 process(image) 함수에 넘기고 언어가 이미지를 복사하면, 픽셀을 복사하는 데 RAM 10MB와 CPU 시간을 낭비한다. 포인터라면 주소(8바이트)만 전달하면 된다. 함수는 이미지가 어디 있는지 알고 그곳을 보러 간다.
변수를 값으로 넘기면 함수는 복제본을 받는다. 복제본을 바꿔도 원본은 그대로다. 포인터를 넘기면 함수는 원본이 어디에 사는지 안다. 실제 데이터를 바꿀 수 있다.
연결 리스트, 트리, 그래프는 다른 데이터 덩어리를 가리키는 포인터를 담은 데이터 덩어리다. 참조 없이 이것들을 만들기는 어렵다.
포인터는 공짜가 아니다.
포인터는 코드와 하드웨어를 잇는 다리다. 고수준 JavaScript나 Python을 쓸 때도 만지는 객체는 속으로는 참조다. 그래서 a = b는 a를 b와 같은 데이터를 가리키게 한다.
© Melvin Laplanche - All rights reserved.