void포인터와 전역, 정적포인터
void포인터와 전역, 정적포인터
Understanding and Using C Pointers: Core Techniques for Memory Management 1st Edition을 읽고 정리한 내용을 기술합니다.
Understanding and Using C Pointers 정리 시리즈
void 포인터
void 포인터는 어떤 타입의 데이터도 참조할 수 있는 범용 포인터다. 아래에 void 포인터 선언의 예제가 있다.
void *pv;
void 선언에는 두 가지 흥미로운 것이 있다.
- void 포인터는 char 포인터와 같은 표현과 메모리 정렬 방법을 사용한다.
- void 포인터는 다른 포인터와 절대 같지 않다. 하지만 NULL 값이 할당된 두 개의 void 포인터는 서로 같다. void 포인터의 실제 동작은 시스템에 따라 다르다.
⚠️ void 포인터는 데이터 타입의 포인터에 사용되며, 함수 포인터에는 사용되지 않는다.
#include <stdio.h> void Foo() { printf("I'm Foo"); } int main() { void (*ptr)(); // void포인터가 아닌, 반환형이 void임. ptr = Foo; ptr(); return 0; }
void 포인터 사용시에는 주의가 필요하다. 임의의 포인터를 void 포인터로 캐스팅한 후, 기존 타입이 아닌 전혀 다른 타입의 포인터로 캐스팅하더라도 이를 막을 방법이 없다.
=> C++에서는 4가지 타입의 안전한 캐스팅 방법을 제공함. static_cast외 참조.
void 포인터에 sizeof
연산자가 사용될 수 있다.
그러나 아래에 보이는 것처럼 void 자체는 sizeof
연산자를 사용할 수 없다.
size_t size = sizeof(void*); // 유효함
size_t size = sizeof(void); // 유효하지 않음
여기서 사용된 size_t는 크기를 나타내는 타입이며, 다음 포스팅에 나오는 “미리 선언된 포인터와 관련된 타입” 절에서 자세히 다룰 것이다.
전역 포인터와 정적 포인터
포인터가 전역 또는 정적으로 선언되면 해당 포인터는 프로그램 시작 시에 NULL로 초기화된다. 아래는 전역 포인터와 정적 포인터 선언의 예를 보여준다.
int *globalpi;
void foo() {
static int *staticpi;
...
}
int main() {
...
}
그림은 위 코드의 메모리 상태를 보여준다. 스택 프레임(Stack frame)이 스택에 입력되고 힙(Heap) 영역은 동적 메모리 할당에 사용된다. 힙 위에 있는 영역은 정적(static)/전역(global) 변수를 위해 종종 사용된다. 그림은 단지 개념을 설명하기 위한 것이며, 정적 변수와 전역 변수는 종종 스택과 힙이 위치한 데이터 세그먼트와는 분리된 별도의 데이터 세그먼트에 위치한다.