Search

char * 타입의 주소 출력 문제

Created
2021/02/26
tag
C++
char * 주소 출력

1. 문제 확인 및 테스트

아래와 같은 코드가 있다고 하자.
#include <iostream> int main() { char A[100]; char *ptr; ptr = A; std::cout << ptr << std::endl; ptr = &A[0]; std::cout << ptr << std::endl; ptr = &A[1]; std::cout << ptr << std::endl; return (0); }
C++
기존에 알던대로, & 연산자를 이용하여 주소를 취득해 ptr에 할당하고 출력해보면 정상적으로 주소 값이 출력되어야 할 것이다.
하지만 배열의 시작점을 참조하도록 A라는 이름을 할당한 경우, A0번째를 참조하여 할당한 경우, A1번째를 참조하여 할당한 경우들에 대해서 모두 주소 값이 찍히지 않은 것을 볼 수 있다.
cout<< 연산자 문제라고 생각할 수도 있었지만, 입출력 관련해서 char 타입이 문제가 많았던 것이 생각이 나서 char *가 문제인가 하는 생각이 먼저 들었다. 이에 따라 char *가 아닌 non-char 포인터에 대해서도 주소가 찍히지 않는가를 실험해보았다.
#include <iostream> int main() { int A[100]; int *ptr; ptr = A; std::cout << ptr << std::endl; ptr = &A[0]; std::cout << ptr << std::endl; ptr = &A[1]; std::cout << ptr << std::endl; return (0); }
C++
위의 그림을 보면 int * 타입으로 이용했을 때는 주소 값이 잘 찍히는 것을 볼 수 있었다. 왜 이번에도 cout에 대해서는 함수의 주소 출력 뿐 아니라 char *의 주소 출력에도 문제가 있는 것일까?
함수의 주소 출력에 대한 글은 여기를 눌러 확인해보자.

2. 문제 원인 및 해결 방법

char *로 된 포인터참조 값을 찍으려 했을 때 잘 되지 않았던 이유는 바로 iostream에서 ostream과 관련이 있다.
ostream이용 시에 C++char *string으로 인식하게 되는데 C++string 특성 상 문자열의 끝을 알리는 '\0'가 들어오지 않는 문자열이 끝이 났다고 인식하지 않는다. 따라서 주소가 출력되지 않고 빈 칸으로 출력된다. (C++에서 string'\0'이라고 하는 NULL이 들어오면 끝으로 인식하는 Zero-Terminated 구조이다.)
따라서 non-char 포인터int *, double * 등은 위와 같은 문제가 없지만 char*는 주소를 출력하려고 할 때, 문제가 발생하는 것이다.
성공적으로 주소를 출력하기 위해선 char * 타입의 변수를 non-char 포인터 타입으로 형 변환 해주면 되는데, 이에 대해선 Generic 타입이 가장 적합한 선택지이다. 따라서 std::cout << ptr << std::endl 할 때 ptrvoid *로 형 변환하면 된다.
포인터의 형 변환이므로 reinterpret_cast를 이용한다.
#include <iostream> int main() { char A[100]; char *ptr; ptr = A; std::cout << reinterpret_cast<void *>(ptr) << std::endl; ptr = &A[0]; std::cout << reinterpret_cast<void *>(ptr) << std::endl; ptr = &A[1]; std::cout << reinterpret_cast<void *>(ptr) << std::endl; return (0); }
C++
아래 그림과 같이 주소가 잘 출력되는 것을 볼 수 있다.