C: alloca() 의 함정

C 언어로 프로그래밍을 하면서 가장 불편했던 것 중의 하나가 메모리 할당과 해제였다. 할당은 하되 알아서 해제해 주면 얼마나 좋을까? 라는 생각을 많이 했었다. C++ 같은 언어는 다양한 기법이 개발되면서 이에 대한 문제를 대폭 해소할 수 있었지만...

이런 불편을 많은 사람들이 공감했는지 비표준적인 방식으로 나름의 해결방법을 제안했다. 그 중의 하나가 alloca() 이다.

C 언어에서 메모리를 할당하면 꼭 해제해야 하는 이유는 메모리가 힙에 할당되기 때문이다. 그래서 alloca() 는 메모리를 스택에 할당한다. 함수가 끝나면 스택은 자동으로 복구가 되니까.

문제는 여기에서 발생한다. alloca() 로 할당한 메모리는 함수가 끝날 때까지 살아 있다. 어디에서 할당하든 함수가 끝날 때까지 상태가 유지된다.

만약 alloca() 를 반복문 안에서 사용하면 어떻게 될까? 

보통 alloca() 를 반복문 안에서 사용하는 이유는 다음 두 가지 기대 때문일 것이다.

첫째, 반복문 범위(scope) 안에서 자동 소멸할 것이다.

둘째, alloca() 로 할당된 메모리는 함수가 끝날 때까지 유효하므로 반복문 안에서 한 번만 할당할 것이다.

하지만, 두 가지 모두 잘못된 생각이다.

alloca() 로 할당된 메모리가 해제되는 기준은 함수가 끝날 때이지, 특정 범위가 끝날 때가 아니고, alloca() 는 호출될 때마다 스택에 메모리 공간을 할당한다.

결국 어떤 결과가 생길까? 바로 스택 공간 부족(out of stack space)이다. 반복문 내에서 계속 스택 공간을 소모하기 때문이다. 따라서 alloca() 는 반복문 안에서 쓰면 안된다.

대신에 C99 을 쓴다면 VLA(Variable-length Array)를 쓰자. VLA 는 alloca() 와 달리 변수가 선언된 범위가 끝날 때 자동으로 소멸한다. 반복문 안에서 쓰더라도 alloca() 와 같은 문제는 발생하지 않는다.

그런데 VLA 에 대해 유의할 것은 C11 에서는 필수가 아닌 선택으로 바뀌었다. 다시 말해서, C11 을 쓰는 경우 컴파일러에 따라 지원할 수도 있고, 안 할 수도 있다.

댓글

이 블로그의 인기 게시물

토렌트: < 왕좌의 게임 > 시즌 1 ~ 시즌 8 완결편 마그넷

토렌트: NGC < 코스모스 > 우리말 더빙 전편(1편~13편) 마그넷

토렌트: < 스타워즈 > Ep.1 ~ Ep.6 마그넷