• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    미해결

[연습문제] nullptr 과 \0 관련 질문 2가지

20.12.27 21:23 작성 조회수 234

1

안녕하세요. 수강생입니다. 
연습문제를 풀다가 다음과 같은 현상을 발견해서 질문합니다. 

첫번째 시도로 

처럼 작성하였는데 정상적으로 작동하는 것을 확인하였습니다.

Q1 . 그래서 다음과 같이 nullptr을 이용하여 작성하니 쓰레기 값까지 같이 출력되는 문제가 생겼습니다. 
nullptr을 제가 어떤식으로 잘못 사용하고 있는지 알려주실 수 있나요? 

이렇게 작성한 의도는 ptr이 널 포인터가 되는 순간 작동을 종료하기 위함입니다. 



*아래와 같이 작성할 경우 제대로 나옵니다. NULL이 매크로로 0으로 지정되어 있어 그런 것 같습니다. 



Q2. 포인터에 증감 연산자 사용 문제 
while (*ptr != NULL)

{ cout << *(ptr); ++ptr; }

라고 작성하였을 때 while 문에서 ptr++ 을 하고 

 *ptr을 출력하면 j 부터 시작이 되지 않습니다.
++ptr로 인하여 그런 것 같은데 이경우에는 어떤식으로 초기화를 해야 j 를 출력하게 할 수 있을까요?

char* ptr = name; 를 써서 초기화를 하는 줄 알았는데 그러면 할당을 여러번 한다고 컴파일 에러가 나옵니다. 

읽어주셔서 감사합니다. 

답변 2

·

답변을 작성해보세요.

5

안소님의 프로필

안소

2020.12.27

Q1. ptr은 절대 nullptr이 되지 않기 때문입니다.

*ptr은 ++ptr을 통해  "Jack jack" 문자열의 원소들을 순서대로 순회하다 보면 문자열 끝의 '\0'을 반드시 만나게 되죠. 그래서 *ptr != NULL을 반복 조건문으로 잡으면 while문은 문자열 끝에 도달하면 꼭 종료가 됩니다. 

그러나 while문 조건문을 ptr != nullptr 로 잡으시면 무한 루프에 빠집니다. 간접 참조를 하는 *ptr이 아닌 포인터 그 자체인 ptr이 0 이 된다는 보장이 있나요? 없습니다..! nullptr 은 0000000 이런 형태의 주소 버전의 0을 의미하는데 ptr의 값이 0이 된다는 보장은 없습니다. 그저 ptr은 ptr++을 통해 증가되고 있을 뿐이니까요. 

while문 조건문을 ptr != nullptr 로 잡고 돌려보았습니다.

ptr이 "Jack jack" 문자열의 끝인 '\0'을 가리키게 되었을 때 이 '\0'의 주소가 0000000 즉 nullptr인 것은 아니죠! 그러므로 ptr은 "Jack jack" 문자열 순회를 끝냈음에도 불구하고 ptr != nullptr 조건을 만족하므로 계속해서 ptr++을 통해 주소값이 증가되어 쓰레기값이 들어있는, 아무 값도 할당 되어있지 않는,  "Jack jack" 문자열 범위를 벗어난 공간까지도 접근하게 되고 그 메모리들의 쓰레기값들을 가져오게 되는 것입니다. 이런식으로 무한 루프에 빠지게 됩니다. ptr 값이 00000000인 주소에 도달한다는 보장이 없으니까요! 제가 while문을 빠져나오면 "잘 종료되었습니다" 가 출력 되게끔 해봤는데 출력이 안된 것을 확인할 수 있습니다. 그리고 문제 없이 잘 종료가 되면 콘솔창에 (코드 : 0개) 가 뜨는데 -1073741819개... 라는 이상한 값이 뜨는 것을 확인할 수 있네요. 잘못된 메모리에 무한정으로 접근하려고 하니 프로그램이 강제 종료되었기 때문입니다. 

따라서 while문 조건문을 *ptr != '\0' (혹은 NULL)으로 잡으시는 것이 좋을 것 같습니다.

Q2. 

초기화에 관련된 말씀이 잘 이해가 되지 않습니다. ㅠㅠ 

이렇게 ptr++ 먼저하고 *ptr 을 출력하면 j가 안나오니까 ptr++ 먼저하고 *ptr 을 출력하더라도 앞 글자 j 부터 시작할 수 있는 방법에 대해 질문 주신게 맞을까요? (이것에 대한 답변을 밑에 작성해 보았는데 혹시 제가 질문자님 의도를 잘못 짚었다면 답글 다시 한번 더 부탁드립니다.)

ptr++; cout << *ptr; 이렇게 두 문장으로 따로 나눠버리면 어차피 *ptr 에선 증가 완료되어버린 ptr 을 간접참조하게 되므로 앞글자 j 부터 시작하지 않는 것이 당연해집니다.

후위증가연산자인 ptr++ 을 쓰고싶으시다면 위와 같이 해볼 수 있겠습니다. 첫 문자부터 출력을 하려면 ptr 이 증가되기 전의 값을 사용해야하므로 증가되기 전의 값을 *ptr 에 넘겨주고 이를 출력할 수 있도록 하시면 됩니다.

0

이동은님의 프로필

이동은

질문자

2020.12.31

확인하고 답글다는 게 늦었습니다. 

1,2 모두 제가 하고자 하는 질문의 의도를 정확하게 파악하셨고, 그에 맞게 답변해주셨습니다. 
쉽게 읽히도록 쓰인 친절한 답변에 많은 도움을 받았습니다. 
정말 감사합니다!