강의

멘토링

커뮤니티

Cộng đồng Hỏi & Đáp của Inflearn

Hình ảnh hồ sơ của properhuman6145
properhuman6145

câu hỏi đã được viết

C++ Học Theo và Thực Hành của Hong Jeong Mo

6.9 Số học con trỏ và lập chỉ mục mảng

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

Viết

·

445

1

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

첫번째 시도로 

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

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

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



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



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

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

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

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

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

읽어주셔서 감사합니다. 

C++

Câu trả lời 2

5

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

properhuman6145님의 프로필 이미지
properhuman6145
Người đặt câu hỏi

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

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

Hình ảnh hồ sơ của properhuman6145
properhuman6145

câu hỏi đã được viết

Đặt câu hỏi