[연습문제] nullptr 과 \0 관련 질문 2가지
466
작성한 질문수 3
안녕하세요. 수강생입니다.
연습문제를 풀다가 다음과 같은 현상을 발견해서 질문합니다.
첫번째 시도로
처럼 작성하였는데 정상적으로 작동하는 것을 확인하였습니다.
Q1 . 그래서 다음과 같이 nullptr을 이용하여 작성하니 쓰레기 값까지 같이 출력되는 문제가 생겼습니다.
nullptr을 제가 어떤식으로 잘못 사용하고 있는지 알려주실 수 있나요?
이렇게 작성한 의도는 ptr이 널 포인터가 되는 순간 작동을 종료하기 위함입니다.
*아래와 같이 작성할 경우 제대로 나옵니다. NULL이 매크로로 0으로 지정되어 있어 그런 것 같습니다.
Q2. 포인터에 증감 연산자 사용 문제
while (*ptr != NULL)
{ cout << *(ptr); ++ptr; }
라고 작성하였을 때 while 문에서 ptr++ 을 하고
*ptr을 출력하면 j 부터 시작이 되지 않습니다.
++ptr로 인하여 그런 것 같은데 이경우에는 어떤식으로 초기화를 해야 j 를 출력하게 할 수 있을까요?
char* ptr = name; 를 써서 초기화를 하는 줄 알았는데 그러면 할당을 여러번 한다고 컴파일 에러가 나옵니다.
읽어주셔서 감사합니다.
답변 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
확인하고 답글다는 게 늦었습니다.
1,2 모두 제가 하고자 하는 질문의 의도를 정확하게 파악하셨고, 그에 맞게 답변해주셨습니다.
쉽게 읽히도록 쓰인 친절한 답변에 많은 도움을 받았습니다.
정말 감사합니다!
변수가 메모리에 저장되는 것을 알려주는 강의가 어떤강의였죠
1
463
1
메모리 주소 10진수로 출력
1
653
1
클래스 템플릿 특수화에서 boolalpha로 표현된 리턴값에 대해 질문이 있습니다.
1
498
1
여러가지 리턴 타입에 관한 강의가 어떤 걸까요?
1
534
1
메모리 주소에 관한 질분
0
678
1
인터페이스 클래스에서 reportError의 매개변수에 대해 궁금한 것이 있습니다.
0
548
1
형변환 오버로딩에서 const 관련 질문이 있습니다.
0
443
1
Digit 뒤에 reference를 사용하는 이유
0
509
1
4.2 전역 변수, 정적 변수, 내부 연결, 외부 연결
0
322
1
dat파일이...
0
537
1
TODO:대입 연산자 오버로딩에 대한 소스코드입니다.
0
643
1
복사 생성자 관련 질문이 있습니다.
0
453
1
수업 중 궁금한점이 있습니다.
1
389
1
라이브러리자체가 이해가 되지 않습니다.
0
561
1
마지막 예제 질문
0
302
1
증감연산자 위치에 따른 수행 순서 질문입니다.
0
374
1
단항 연산자 오버로딩에서 return 부분에 질문이 있습니다.
1
410
1
friend함수 관련 질문이 있습니다.
0
311
1
operator+ 정의부분에서 궁금한 것이 있습니다.
0
447
1
3분 17초 질문
0
350
1
함수에 값을 대입한다는 개념이 이해가 되지 않습니다.
0
446
1
int getvalue() const에서 const는 왜 뒤에 붙는건가요?
0
442
2
const Something &st에서 const를 빼면 안되나요?
0
300
1
friend함수는 다른 클래스의 멤버함수로 쓸 수 없나요??
1
491
1





