널 포인터

위키백과, 우리 모두의 백과사전.

널 포인터(null pointer)는 유효한 객체를 참조하지 않는 포인터를 나타내기 위해 예약된 값을 갖는다. 프로그램들은 일상적으로 알려지지 않은 길이를 가진 리스트의 끝이나 특정한 행동 수행 실패 같은 조건들을 표현하기 위해 널 포인터를 사용한다; 널 포인터들의 이러한 사용은 Nullabe 타입들, 옵션 타입에서의 Nothing 값과 비교될 수 있다.

널 포인터는 반드시 초기화되지 않은 포인터와 혼동되어서는 안된다: 널포인터는 유효한 객체를 가리키는 어느 포인터와 비교해도 같지 않게 보장된다. 그러나 언어와 구현에 따라서, 초기화되지 않은 포인터는 이것을 보장하지 않는다. 초기화되지 않은 포인터 다른 유효한 포인터들 또는 널 포인터들과 비교해서 같을 수 있다. 즉, 초기화되지 않은 포인터는 때에 따라서 두 경우 모두가 될 수 있다.

널 포인터는 널 값과는 다른 의미를 갖는다. 대부분의 프로그래밍 언어에서 널 포인터는 "값 없음"을 의미하지만, 관계형 데이터베이스에서 널 값은 "알려지지 않은 값"을 의미한다. 이것은 실질적으로 중요한 차이로 이끌어 진다: 대부분의 프로그래밍 언어들은 두 널 포인터를 같다고 여기지만, 관계형 데이터베이스 엔진은 두 널 값을 같다고 여기지 않는다(왜냐하면 이것들은 알려지지 않은 값들을 의미해서, 이것들이 같은지도 알려져 있지 않으므로).

C[편집]

C에서, 어느 타입의 두 널 포인터들도 비교해서 같다고 보장이 된다.[1] T매크로 NULL 은 구현 정의된 널 포인터 상수로 정의되는데,[2] 이것은 C99에서 간편하게 정수 값 0 으로 표현되며, 암묵적으로 또는 명시적으로 타입 void*으로 변환된다.[3]

널 포인터를 역참조하는 것은 일반적으로 매핑되지 않은 메모리(세그멘테이션 오류나 접근 위반을 유발하는)를 읽거나 쓰려는 시도를 초래한다. 이것은 개발자에게 스스로 프로그램 충돌을 의미하거나 잡힐 수 있는 예외로 변형된다. 그러나 이 경우가 아닌 환경이 존재한다. 예를 들면 x86 실제 모드에서, 주소 0000:0000은 읽을 수 있고, 보통 쓸 수 있으므로, 널 포인터를 역참조하는 것은 완벽하게 유효하지만 일반적으로 애플리케이션에서 원치 않은 행동(정의되지 않았지만 충돌하지 않는 행동)으로 이어진다. 의도적이고 잘 정의된 널을 역참조할 때 여러 경우들 또한 존재한다는 점을 주의하라; 예를 들면 16비트 리얼 모드 x86 디바이스에서 C로 짜여진 BIOS 코드는 머신의 물리 주소 0에 쓰기 위한 용도로 NULL 포인터를 역참조함으로써 IDT를 쓴다. 또한 컴파일러가 세그멘테이션 오류를 피하기 위해 'NULL' 포인터 역참조를 최적화하지만 다른 의도되지 않은 행동을 유발할 가능성이 있다.

C++[편집]

C++에서는 NULL 매크로를 C로부터 상속 받았지만, 0을 위한 정수 리터럴이 전통적으로 널 포인터 상수를 표현하는 것보다 더 선호되고 있다.[4] 하지만 C++11은 명시적 nullptr 상수를 도입해서 이것 대신 사용되도록 하였다.

역참조[편집]

널 포인터가 의미있는 객체를 가리키지 않기 때문에, 널 포인터를 역참조하려는 시도는 보통(하지만 항상은 아닌) 런타임 오류나 즉각적인 프로그램 충돌을 유발한다.

  • C에서, 널 포인터를 역참조하는 행동은 정의되어 있지 않다.[5] 널 포인터 표현이 저장된 객체들을 위해 시스템에 의해서 절대 할당되지 않는 주소로 선택되기 때문에, 많은 구현들은 이러한 코드가 세그멘테이션 오류와 함께 멈춰지게 하는 결과를 초래시켰다. 그러나 이 행동은 일반적이지는 않다.
  • Java에서, 널 참조에 대한 접근은 NullPointerException (NPE)을 초래하는데, 이것은 오류 처리 코드에 의해 잡힐 수 있지만 선호되는 것은 이러한 예외들이 절대 일어나지 않게 하는 것이다.
  • .NET에서, 널 참조에 대한 접근은 NullReferenceException가 던져지는 결과를 초래한다. 비록 이것들을 잡는 것이 일반적으로 좋지 않은 사용이지만, 이 예외 타입은 프로그램에 의해 잡히고 처리될 수 있다.
  • Objective-C에서, 메시지들이 프로그램이 인터럽트되는 것을 유발시키지 않으며,  nil 객체(널 포인터이다)로 보내질 것이다. 메시지는 간단하게 무시되며 반환 값은 타입에 따라 nil 또는 0이 된다.[6]

각주[편집]

  1. ISO/IEC 9899, clause 6.3.2.3, paragraph 4.
  2. ISO/IEC 9899, clause 7.17, paragraph 3: NULL... which expands to an implementation-defined null pointer constant.
  3. ISO/IEC 9899, clause 6.3.2.3, paragraph 3.
  4. Stroustrup, Bjarne (March 2001). 〈Chapter 5: Pointers, Arrays, and Structures: 5.1.1: Zero〉. 《The C++ Programming Language》 14 printing of 3판. United States and Canada: Addison–Wesley. 88쪽. ISBN 0-201-88954-4. In C, it has been popular to define a macro NULL to represent the zero pointer. Because of C++'s tighter type checking, the use of plain 0, rather than any suggested NULL macro, leads to fewer problems. If you feel you must define NULL. use: const int NULL = 0;The const qualifier (§5.4) prevents accidental redefinition of NULL and ensures that NULL can be used where a constant is required. 
  5. ISO/IEC 9899, clause 6.5.3.2, paragraph 4.
  6. The Objective-C 2.0 Programming Language, section "Sending Messages to nil".

외부 링크[편집]