인프런 커뮤니티 질문&답변

김민수님의 프로필 이미지
김민수

작성한 질문수

홍정모의 따라하며 배우는 C언어

9.15 NULL 포인터와 런타임 에러

NULL을 이해한건지 알고싶습니다.

해결된 질문

작성

·

274

0

안녕하세요, 질문이 있습니다.

제가 이해한게 맞는건지 확인하고자 합니다.

int* a = NULL; 을 사용한다는 것은

int b;

scanf("%d", &b)

if (b % 2 == 0)

a = &b;

처럼 입력값에 따라 실제 메모리 공간을 할당받은 메모리주소를 가진 변수b를

조건이 true일 경우 제대로 대입이되서 사용이 가능한거고

조건이 false일 경우 그대로 NULL인 값을 포인터 변수 a가 가지고 있을때

포인터 변수 a를 이용하는 구문을 만났을때

printf("%p %d", a, *a); 이대로 실행하면 런타임 에러가 발생하기 때문에 이걸 방지하고자

if (a != NULL)

   printf("%p %d", a, *a);

이것처럼 조건을 걸어 제대로 값을 대입받았다면 실행이 되고 그러지 아니하면 실행이 안되고 그냥 런타임 에러 없이 넘어가기 위함 인가요?

제가 한번더 확인하고자 NULL 말고 int *a = 1; 을 한다음

if (a != 1)

  printf("%p %d", a, *a);

을 해도 런타임 에러없이 그냥 넘어가더라구요

그래서 NULL로 초기화 해준게 a포인터 변수를 이용하는 구문을 만났을때 그냥 적어두면 오류가 발생하니 조건의 기준을 정하기 위해 임시로 NULL을 넣은게 아닌가 생각했습니다.

* 두번째 질문. *

NULL을 눌러서 vcruntime.h 로 들어가서 보니

((void *) 0) 이라고 define으로 되어 있더라구요

이 의미는 다른의미가 있나요? 아니면 0과 같나요?

실제 NULL하고, 0을 int *a 포인터 변수에 초기화를해서 %p로 출력해보니까 둘다 같은 16진수인 00000000 으로 나오더라구요. 같은건지 아니면 다른의미가 있는데 이어지는 강의에서 나오는건지 궁금합니다.

답변 1

2

첫 번째 질문

그렇다고 볼 수 있을 것 같아요. 포인터 변수를 미리 초기화 해두긴 해야 하는데(포인터는 초기화하지 않고 사용하면 위험하기 때문에 컴파일조차 되지 않죠) 질문자님처럼 1 이나 뭐 1234 이런걸로 초기화 해놓고 if(a != 1234) 이래도 런타임 에러 방지하는데 아무 문제 없겠지만, 1234 는 유효한 주소도 아닐 뿐더러 코드를 읽는 사람 입장에서 이 1234 가 뭐지..? 무슨 의미지? 할 수도 있겠죠. 그래서 관습적으로 NULL 값으로 포인터를 초기화해두는 것입니다. 어떠한 대상도 가리키지 않는 포인터 상태를 NULL 이라고 하자 라고 약속한 느낌이라고 생각하시면 될 것 같아요 .코드 읽는 사람 입장에서 if(a != 1) 보단 if(a != NULL) 이 더 '아 포인터가 뭔가를 가리키고 있는 상태일 때 실행하는 if문이구나' 라고 바로 납득할 수 있는 코드겠죠?

두 번째 질문

네. NULL 은 타입이 void* 인 0 이라고 정의가 되어 있습니다. 전처리 과정에서 NULL 은 (void*)0 로 대체가 됩니다. C++ 표준 만드신 분께서 NULL 은 0 이라고 정의해두신 것 같아요.(0000000 이런 주소값이 0 이라는거죠) 꼭 0 이어야 하는 특별한 의미가 있다기보단 앞서 말씀드린 약속, 관습적 개념에서 설정한거라고 생각해주시면 될 것 같아요. 만약 C++ 표준 만드신 분이 아무것도 가리키지 않는 상태일 때를 1234 라고 하기로 하자! 라고 했으면 NULL 은 1234 를 의미했을 것입니다. 

김민수님의 프로필 이미지
김민수

작성한 질문수

질문하기