gcc builtin: alloca

The alloca() function allocates size bytes of space in the stack frame of the caller. This temporary space is automatically freed when the function that called alloca() returns to its caller.
April 6, 2026

gcc builtin: alloca

Reqruies
  • Compiler: gcc 2.8 later
GCC 내장 함수 중 하나인 __builtin_alloca에 대해 살펴보겠습니다.
가장 먼저 기억해야 할 점은, 많은 서적과 포스트에서 alloca 내장 함수를 보안상의 이유로 사용하지 말라고 권고한다는 것입니다.
이번 포스트를 통해 그 이유를 명확히 이해하실 수 있기를 바랍니다.
오픈소스 코드를 많이 보셨다면 __builtin_alloca를 자주 접하셨을 것입니다.
예를 들어, glibc의 strdupa 매크로는 다음과 같이 정의되어 있습니다.
strdupa macro (glibc/string/string.h)
c
__builtin_alloca는 동적으로 메모리를 할당할 때 heap이 아닌 stack 공간을 사용하도록 하는 GCC 내장 함수입니다.
따라서 glibc의 strdupa 코드를 보면 별도로 free()를 호출하지 않는 것을 확인할 수 있습니다.
malloc()처럼 힙 공간에 할당되지 않기 때문에, 할당된 메모리의 수명(life-time)은 해당 코드가 포함된 함수 스코프(function scope)에 종속됩니다.
일반적인 지역 변수와 마찬가지로 별도의 free() 호출 없이, 호출자 함수(caller)로 반환될 때 스택 포인터를 복원하는 것만으로 자연스럽게 메모리 해제 효과를 얻을 수 있습니다.
결과적으로 malloc() 호출에 비해 cpu-timememory 사용 측면 모두에서 이점이 있습니다.

How it works

__builtin_alloca는 일반 함수처럼 런타임에 호출되는 것이 아니라, compile-time에 GCC에 의해 인라인 코드로 변환 처리되는 내장 함수입니다.
매크로와 유사하게 사용되지만 엄밀히 말해 매크로는 아닙니다.
디스어셈블을 통해 __builtin_alloca가 GCC에 의해 다른 코드로 변환되는 것을 확인할 수 있습니다.
builtin_alloca replacement example
bash
callq __builtin_alloca와 같은 일반적인 함수 호출 형태가 아닌, 스택 레이아웃을 직접 조작하는 형태(sub %rax,%rsp 등)임을 확인할 수 있습니다.
이 빌트인은 메모리를 동적으로 할당하지만, 지역 변수처럼 특정 함수 내에서 일시적으로만 사용될 것이 보장되는 곳에서 주로 활용됩니다.
GCC 문서를 살펴보겠습니다.
Built-in Function: void *__builtin_alloca (size_t size)
Doc

The __builtin_alloca function must be called at block scope.

The function allocates an object size bytes large on the stack of the calling function. The object is aligned on the default stack alignment boundary for the target determined by the BIGGEST_ALIGNMENT macro.

The __builtin_alloca function returns a pointer to the first byte of the allocated object. The lifetime of the allocated object ends just before the calling function returns to its caller.

This is so even when __builtin_alloca is called within a nested block.

GCC 코드를 자세히 보지는 않았지만, GCC 2.8부터 존재해 온 빌트인입니다.

Sample code

샘플 코드를 통해 사용법을 간단히 확인해 보겠습니다.
sample code - alloca.c
c
Execution Result
bash
assembly - x86_64 AT&T
bash
메모리 정렬(align) 루틴 역시 컴파일러에 의해 추가되었지만 가장 중요한 부분은 메모리 확보를 위해 스택 공간만 일시적으로 확장해 사용하고, 반환 시 leaveqretq를 통해 스택 포인터를 원래대로 복원함으로써 별도의 free() 호출 없이 자연스럽게 메모리가 해제된다는 점입니다.

Scope

GCC 문서에서는 스코프에 대해 다음과 같이 설명합니다.
The lifetime of the allocated object ends just before the calling function returns to its caller
glibc 1.09에서는 긴 이름을 줄이기 위해 __builtin_allocaalloca로 정의했습니다.
__builtin_alloca is defined as alloca in glibc/stdlib/alloca.h
c
따라서 alloca.h를 포함하면 단순히 alloca 매크로명을 통해 편하게 사용할 수 있습니다.
하지만 개인적으로는 해당 기능이 런타임에 호출되는 일반 함수가 아니라 컴파일 타임에 치환되는 빌트인인 점을 명확히 드러내기 위해, __builtin 접두사를 생략하지 않고 그대로 표현하는 것이 더 직관적이라고 생각합니다.
물론 이는 단순한 코딩 스타일의 문제이므로, 협업 프로젝트라면 정해진 코딩 규칙(Coding Rules)을 따르면 됩니다.
C99에서 지원하는 VLA (Variable-Length Array; 컴파일 타임이 아닌 런타임에 크기가 결정되는 가변 길이 배열)와 유사해 보이지만, 할당된 메모리의 수명(lifetime)이 다릅니다.
VLA의 수명은 블록 스코프(block scope)인 반면, alloca는 함수 스코프(function scope)입니다.
즉, VLA는 다음과 같은 상황에서 사용할 수 없습니다.
VLA vs alloca lifetime example
c

Security concerns

앞서 언급했듯이, 스택에 가변적인 크기의 메모리를 할당하는 VLA나 alloca는 보안상 위험 요소가 될 수 있으므로 많은 매체에서 사용을 지양하라고 권고하며, 저 역시 이에 동의합니다.
스택에 크기가 동적으로 결정되는 메모리를 할당하게 되면 자칫 스택 오버플로우(Stack Overflow)를 유발할 수 있으며, 이는 심각한 보안 취약점 공격 대상이 될 수 있습니다.
또한 할당 길이에 음수가 전달될 경우, 아주 큰 양수로 해석(size_t)되어 스택 포인터가 꼬이면서 전혀 의도하지 않은 형태로 프로그램이 동작할 수 있습니다.
그리고 C 언어에서 동적 할당의 표준으로 널리 사용되는 malloc/free 패턴과 라이프사이클이 다르다 보니, alloca의 메모리 관리 기법에 익숙하지 않은 개발자에게 큰 혼동을 줄 수 있습니다.
alloca is not standard - it is a GNU extension
이러한 이유로 리눅스 커널 프로젝트에서도 코드 베이스 내의 VLA를 제거하기 위해 많은 노력을 기울였고, 결과적으로 커널 4.20 버전에서 모든 VLA 사용 코드를 성공적으로 걷어냈습니다.
GNU 문서에서는 alloca의 장점을 다음과 같이 설명합니다.
Advantages-of-Alloca
Doc
  • Using alloca wastes very little space and is very fast. (It is open-coded by the GNU C compiler.)
  • Since alloca does not have separate pools for different sizes of blocks, space used for any size block can be reused for any other size. alloca does not cause memory fragmentation.
  • Nonlocal exits done with longjmp (see Non-Local Exits) automatically free the space allocated with alloca when they exit through the function that called alloca. This is the most important reason to use alloca.
단점은 다음과 같이 설명됩니다.
Disadvantages-of-Alloca
Doc
  • If you try to allocate more memory than the machine can provide, you don't get a clean error message. Instead you get a fatal signal like the one you would get from an infinite recursion; probably a segmentation violation (see Program Error Signals).
  • Some non-GNU systems fail to support alloca, so it is less portable. However, a slower emulation of alloca written in C is available for use on systems with this deficiency.

Safer alloca

GCC 4.7에서는 __builtin_alloca_with_align이 추가되었고, GCC 8.1에서는 __builtin_alloca_with_align_and_max가 추가되었습니다.
alloca를 더 안전하게 사용할 수 있도록 최대 크기(max_size)나 정렬(align)을 설정할 수 있게 된 것입니다.
간단한 추가 사항이므로 문서를 확인해 보시기 바랍니다.
Other-Builtins
Doc
  • Built-in Function: void *__builtin_alloca_with_align (size_t size, size_t alignment)
  • Built-in Function: void *__builtin_alloca_with_align_and_max (size_t size, size_t alignment, size_t max_size)
alloca를 더 안전하게 사용하기 위해, GCC 7.0에는 컴파일 타임에 alloca의 최대 크기를 확인할 수 있는 컴파일 옵션이 추가되었습니다.
또한 코드에서 alloca가 사용되고 있는지 여부도 확인할 수 있습니다.
-Walloca-larger-than, -Walloca ...

Conclusion

불가피하게 alloca를 사용해야 한다면, 할당 크기의 상한과 전달 인자 값의 범위 체크에 각별한 주의를 기울여야 합니다.
특히, 인라인(inline) 함수 내부에서 alloca를 사용할 경우 의도를 벗어난 스택 누수(Stack Leak) 문제가 발생할 수 있으니 주의하시기 바랍니다.
이유는 간단합니다. 메모리 해제 시점이 인라인 함수 자신이 아니라 그것을 호출하고 확장(inline)한 부모 함수(caller)가 런타임에 반환될 때이기 때문입니다.
즉, 반복문 등에서 특정 인라인 함수가 지속적으로 호출될 경우 해당 스택 프레임 내에 메모리가 누적 할당되어 치명적인 스택 오버플로우로 직결될 수 있습니다.
Jooojub
System S/W engineer
Explore Tags
Series
    Recent Post
    © 2026. jooojub. All right reserved.