C언어에서가 현재까지 사라지지 않고 언어 사용 순위 중 상위권을 차지하는 이유 중 하나는 포인터라고 해도 과언이 아닐 것이다.

그만큼이나 C언어를 할 줄 안다고 이야기를 하려고 한다면 포인터는 자유자재로 활용할 정도의 수준을 의미하며, 즉, C언어에서 포인터를 사용할 줄 모른다면 C언어를 할 줄 아는 것이 아니라 컴퓨터 프로그래밍이라는 것을 할 줄 안다라고 표현해야 맞을 것이다.


프로그램의 실행은 기본적으로 하드디스크에 저장된 실행파일을 메모리(RAM)로 로드하여, CPU를 통해 명령어를 처리하는 일련의 과정이다. 흔히, C언어를 포기하는 첫 번째 장벽 중 하나가 포인터이며, 이는 메모리 구조에 대한 기초적인 지식조차 없다면 추상적인 의미의 한계에 의해 포기할 수밖에 없게 된다.


이번 포스팅에서는 포인터라는 것이 무엇이고, 어떻게 사용되는지에 관련된 간단한 메모리 참조와 기초 지식에 대해서 다룬다.

Stack, Heap과 같은 메모리 영역에 대해서는 다음 포스팅에서 다룰 예정이며, 간단히 포인터 사용에 있어서 주소(Address)에 대한 개념과 포인터 사용원리에 대한 내용을 중점으로 다룰 것이다.

또한, 32-bit의 4GB 메모리를 기준으로 설명할 것이며, 테스트는 Ubuntu 14.04에서 메모리 가드에 대한 옵션을 제거한 상태에서 설명한다.

 


포인터 사용에 있어 가장 혼동이 오는 부분은 &(앰퍼샌드)와 *(에스테리스크) 사용일 것이다.

이번 포스팅에서는 &(앰퍼샌드)와 *(에스테리스크)​ 사용에 대한 설명을 상세히 설명하고자 한다.

 

 

1. &(앰퍼샌드)의 활용

아래와 같은 코드를 컴파일하여 각각의 변수들에 대한 주소값을 확인해보자.

 


 

&(앰퍼샌드)를 이용하면 할당한 변수의 주소값을 확인할 수 있으며, 해당 주소값은 실행한 시점에서 아래 그림과 같이 할당된 것을 확인할 수 있다.

 

 


이것을 메모리로 도식화한다면 다음과 같이 나타낼 수 있을 것이다.

 

 


포인터 변수는 다음과 같이 변수의 &(앰퍼샌드) 연산자를 이용하여 실질적으로 저장된 메모리 주소(Memory Address)를 저장하는 용도로 사용되며, 이와 같이 변수가 저장된 메모리의 실질적인 주소를 알기 위해서는 &(앰퍼샌드)연산자를 이용하면 가능하다.


이와 같은 원리로 포인터를 사용하여 메모리에 삽입되는 순서를 도식화해보자. 예제 코드는 아래 그림과 같다.

 

 


예제 코드를 실행하면 아래와 같이 각 변수들에 대한 주소값들을 확인할 수 있다.

 

 


이를 도식화하면 메모리에 들어간 변수와 값들은 아래와 같을 것이다.

 

 


이전에 설명한 것처럼 다음과 같이 &(앰퍼샌드)를 이용하여 변수 temp의 메모리 주소를 포인터 변수 ptemp에 저장하는 것을 확인할 수 있다.

 

 

2. *(에스테리스크)의 활용

&(앰퍼샌드)가 변수의 메모리 주소를 확인하는 연산자​라면, 반대로 저장된 변수의 메모리 주소 참조에 활용되는 연산자가 *(에스테리스크)이다.


아래 그림처럼 *(에스테리스크) 활용을 위한 예제 코드를 추가하였다.


 


이를 실행하면 다음과 같은 결과가 나온다.

 

 


이를 도식화하였을 때, *(에스테리스크)를 활용하여 temp2의 변수에 10이 대입​되는지 확인이 가능하다.

 

 

 

3. 흔히 벌어지는 실수

​포인터를 사용하다 보면, 다음과 같은 실수들을 흔하게 마주하게 된다.

 

 


이는 대부분이 포인터를 사용하면서 잘못된 메모리 주소를 참조할 경우 생기는 오류(Segmentation fault)이며, 다음과 같은 간단한 예제를 통해 원인을 살펴보겠다.

 

 


위의 그림처럼 포인터 변수에 프로그래머의 실수로 &(앰퍼샌드)​를 이용하지 않은 채 temp의 값(10)을 대입​하는 경우가 발생하였다. 이를 도식화한 것이 아래의 그림이다.

 

 


다음과 같이 잘못된 메모리 주소 참조로 인해 실행 중 에러가 발생하며, 포인터를 사용할 때 초보자들이 흔히 겪게 되는 오류 중 하나이다. 포인터에 대한 개념과 메모리 주소 참조에 대한 개념 그리고 &(앰퍼샌드), *(에스테리스크)에 대한 용도를 명확하게 이해하고 있는 프로그래머라면 이런 에러가 발생하더라도 적절하게 대응이 가능할 것이다.


+ Recent posts