본문 바로가기
컴터/C, C++

c++ at(-1), [-1] 뭐는 되고? 왜 다르지?

by 나 진짜 못차마 2023. 2. 25.
728x90

VS code로 string을 만지다가 

string으로 선언한 변수에다가 string::npos 위치의 값을 출력하게 된 경우가 있어 수정을 하려했다.

 

(극단적인) 예를 들어,

string test_str = "0123456789";

size_t offset = test_str.find("good");
cout <<"test_str[offset] : " << test_str[offset]<<"\n";

그러고 g++ build 후, 실행해보니

출력

띠용

test_str 에 "good"이란 문자열이 없으니 string::npos를 offset 에 반환.

string::npos 는 unsigned long long MAX value(이전  post 참고) 인데 별 다른 오류 출력이 없었다.

 

-1 을 넣어보자.

출력

여전히 별 다른 오류 출력이 없다.

 

조졌다.  잠 못 잔다.

 

 

at() 함수를 써보자.

string test_str = "0123456789";
    
size_t offset = test_str.find("good");
cout <<"test_str.at(offset) : " << test_str.at(offset)<<"\n";

출력

예스. "out_of_range"  error가 발생한다.

 

사실 이건 c++ at manual 보면 나와있다.

알아서 검사해준다 이거다!

https://cplusplus.com/reference/string/string/at/


근데 여기서 알고 싶은 거는 이게 아니라!

왜 [-1]은 되냐는 것이여 !!

 

-1 잘못 접근하면 책임져줄 것이냐?

는 개발자가 알아서 잘 해야되지만

 

여튼 알아보자.

int 형 배열로 주소값을 살펴봤다.

int arr[10] = {1,2,3,4,5};

cout <<"arr[0] 주소값 : "<< &arr[0]<<"\n";
cout <<"arr[-1] 주소값 : " <<&arr[-1]<<"\n\n";

if(arr[9] == '\0'){
    cout <<"arr[9] = null\n";
}
if(arr[-1] == '\0'){
    cout << "arr[-1] = null\n";
}

 

출력문

당연히 arr[-1] 주소는 arr[0]에서  int 형 크기 만큼 이동(뺀) 값일 것이다.

근데 정의하지 않은 arr[9]의 제대로 null의 값이 배정(?) 되었는데,

arr[-1]은 뭐가 없다.

 

찾아보니

c++에서는 배열이나 문자열의 인덱스를 체크하지 않고 실행한다. ( ' [ ] ' 인덱스 연산자 한해서)

그 이유는 빠른 실행 속도를 가진 c++ 언어 특성상 실행 시간에 추가적인 작업을 최소화한다.
그러나 이러한 잘못된 접근은 "undefined behavior" 즉, 예기치 않은 동작을 발생 시킨다.

 

찾다가 undefined behavior 에 재밌는 설명이 있었다.

Welcome to every C/C++ programmer's bestest friend: Undefined Behavior.
There is a lot that is not specified by the language standard, for a variety of reasons. This is one of them.
In general, whenever you encounter undefined behavior, anything might happen. The application may crash, it may freeze, it may eject your CD-ROM drive or make demons come out of your nose. It may format your harddrive or email all your porn to your grandmother.
...
source : https://stackoverflow.com/questions/1239938/accessing-an-array-out-of-bounds-gives-no-error-why

마지막 문장이 아주 아찔한 미국식 설명이다.

잘 설명하다가 급발진 ㅋㅋㅋㅋ맵다 매워


여튼,

c++에서는 [] 인덱스 연산자에 대해서는 굳이 경계 검사를 시행하지 않으니,

[] 인덱스 연산자를 사용할 때는 아주 주의하여 사용하자 !

 

728x90

'컴터 > C, C++' 카테고리의 다른 글

[C, C++] Pointer(포인터) ( 부제 : 어디서 삿대질)  (0) 2023.08.13
C++ 문자열 숫자 곱하기  (0) 2023.06.16
c++ string :: npos 는 -1 ?  (0) 2023.02.23