본문 바로가기

BackEnd/C

잘못된 포인터 사용의 예와 NULL 포인터

반응형

1. 초기화되지 않은 포인터는 어디를 가리킬지 모른다.

 

지역변수는 선언과 동시에 초기화하지 않으면 쓰레기 값으로 초기화가 된다. 

 

포인터 변수도 지역변수의 형태로 선언하고 초기화하지 않으면 쓰레기 값으로 초기화가 된다.

 

문제는 이 쓰레기 값을 주소 값으로 해석해서 연산하는 경우에 발생한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int main(void)
{
    int * p1;
    double * p2;
 
    /* 쓰레기 값 확인하기 */
    printf("쓰레기 값 1: %#x \n", p1);
    printf("쓰레기 값 2: %#x \n\n", p2);
 
    /* 잘못된 연산 */
    printf("어떤 정수가 찍힐까? %d \n"*p1);
    printf("어떤 실수가 찍힐까? %f \n\n"*p2);
 
    /* 위험한 연산 */
    *p1=25;
    *p2=3.15;
 
    printf("저장된 정수 %d \n"*p1);
    printf("저장된 실수 %f \n\n"*p2);
 
    return 0;
}
cs

1
2
3
4
5
6
7
쓰레기 값 10x785bb6f0
쓰레기 값 20x425f3af0
어떤 정수가 찍힐까? 3683808
어떤 실수가 찍힐까? 0.00000
저장된 정수 858993459
저장된 실수 3.150000
 
cs
 

3~4행 포인터 선언만 하고 초기화를 하지않았다.

 

7~8행 포인터 변수에 쓰레기값이 초기화 되었다.

 

11~12행 저장된 값을 출력하고 있다.

 

문제는 15~16행이다. 25와 3.15로 값을 변경하고 있다. 만약에 이 위치에 매우 중요한 데이터가 저

 

장되어 있다면 운영체제와 관련된 데이터에 손실을 일으켜 큰 문제가 발생할 수도 있다.

 

물론 현재는 운영체제가 자신이 사용하는 메모리 영역의 보호능력을 가지고는 있다.

 

2. NULL 포인터

 

그래서 이와같은 문제를 해결하기 위해 널 포인터를 정의하였다.

 

포인터 변수를 0으로 초기화 시켜두면 아무곳에 대한 주소값도 지니지 않게 된다.

 

0으로 초기화시 NULL 포인터와 같은 의미이다.

 

따라서 0으로 초기화된 NULL 포인터로의 메모리 접근시, 프로그램은 중단된다.

 

중단되는 것이 잘못된 결과를 보이는것보다 안전하다. 디버깅 기회를 제공하기 때문이다.

 

다음 예제를 통해 널 포인터의 안정성을 확인해보자

 

1
2
3
4
5
6
7
8
9
int main(void)
{
    int * ptr=0;
 
    *ptr=100;
    printf("%d"*ptr);
 
    return 0;
}
cs

 

3행에서 포인터 ptr을 널 포인터로 초기화 했다. 0을 대신해서 null을 사용해도 된다.

 

5행에서 100을 저장하고 있는데, 널 포인터는 가리키는 위치가 없어서 프로그램은 종료된다.

 

 

 

반응형

'BackEnd > C' 카테고리의 다른 글

문자열 배열과 문자열을 참조하는 포인터  (0) 2019.03.12
&연산자가 반환하는것은?  (0) 2019.03.12
포인터 형과 *연산자  (0) 2019.03.12
포인터 변수 선언  (0) 2019.03.12
포인터와 메모리  (0) 2019.03.11