C에서 size함수를 조심해야 하는 이유

김효민·2020년 10월 20일
1

TIL

목록 보기
1/3

C++로 작업을 하거나 글쓴이처럼 PS문제를 풀다보면 vector,set,map 같은 Containers library를 사용할 때가 있다. 컨테이너를 사용하다 보면 크기를 return 받기 위해 size 함수는 필수적으로 사용하게 된다. 하지만 자주 사용하면서도 이 메소드를 정확히 알지 못했기에 실수를 하게 됐다. 다시는 이 실수를 반복하지 않기 위해 여기에 남긴다.


문제의 발단

C++로 문제를 풀다가 아래의 코드 처럼 size() - 1번 Loop를 도는 코드를 작성하였다. 코드를 작성 할 때에는 만약 vector가 비어있으면 for문 안으로 안들어가겠지? 라고 생각했다.
//예시 코드
vector<int> v;

for(int i = 0; i < v.size() - 1; i++)
{
	printf("aaa\n");
}

하지만....


예시 코드 결과

결과는 아마 많은 분들 께서 알고 계시겠지만

aaa가 끝도 없이 출력된다...


분석

하지만 뭐가 문제인지 알기 위해서 디버깅 코드를 아래와 같이 잘못 짜게 되면 혼란이 가중된다.

int main()
{
    vector<int> v;
    printf("%d\n", v.size() - 1);

    return 0;
}//결과 값 -1

뭐야.??? 라는 생각이 들 수 밖에 없다.

그래서 일단 size함수를 더 알아보기 위해 reference사이트를 참조해 봤다.

size()의 return value의 타입은 unsigned integral type 이다.
출처

size() 함수의 리턴 값은 unsigned 값이기 때문에 0에서 1을 빼게 되면 언더플로우가 나기 때문에 위의 예시코드가 예상과 다르게 작동한다.

하지만 위의 디버깅 코드는 printf과정에서 %d를 이용했기 때문에 다시 signed int로 인식해서 출력 됐기 때문에 -1라는 값이 나왔다.


검증

int main()
{
    vector<int> v;
    printf("%u\n", v.size() - 1);

    return 0;
}//결과 값 429467295 (2^32 - 1)

드디어 v.size() - 1의 정체(?)를 파악했다


해결책

vector<int> v;

for(int i = 0; i < (int)v.size() - 1; i++)
{
	printf("aaa\n");
}

이런식으로 size함수를 int로 casting하면 의도했던 방식으로 코드가 작동하게 된다.
생각없이 사용하던 라이브러리의 함수들을 이번기회에 더 자세히 살펴볼 수 있어서 다행이라고 생각한다. 역시 라이브러리를 사용할 때에 좀 더 확실히 이해하고 사용해야 겠다.

profile
귀찮음에 민감한 개발자

0개의 댓글