inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

홍정모의 따라하며 배우는 C++

6.9 포인터 연산과 배열 인덱싱

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

466

이동은

작성한 질문수 3

1

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

첫번째 시도로 

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

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

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



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



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

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

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

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

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

읽어주셔서 감사합니다. 

C++

답변 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