스택 기반 메모리 할당
Stack-based memory allocation![]() |
컴퓨팅 아키텍처의 스택은 LIFO(Last-In-First-Out) 방식으로 데이터를 추가하거나 삭제하는 메모리 영역입니다.
대부분의 현대 컴퓨터 시스템에서 각 스레드는 스택이라고 불리는 예약된 메모리 영역을 가집니다.함수가 실행되면 로컬 상태 데이터 중 일부를 스택 상단에 추가할 수 있습니다.함수가 종료되면 해당 데이터를 스택에서 삭제합니다.적어도 스레드의 스택은 반환문이 올바른 위치로 반환되도록 하기 위해 발신자가 제공한 반환 주소의 위치를 저장하기 위해 사용됩니다.
스택은 현재 활성 함수에 대해 로컬로 고정된 길이의 변수를 저장하는 데 자주 사용됩니다.프로그래머는 스택을 명시적으로 사용하여 가변 길이의 로컬 데이터를 저장하도록 선택할 수도 있습니다.메모리의 영역이 스레드의 스택에 있는 경우, 그 메모리는 스택에 할당되어 있다고 합니다(스택 베이스 메모리 할당(SBMA)).이는 힙 기반 메모리 할당(HBMA)과 대조됩니다.SBMA는 많은 경우 함수 콜스택과 밀접하게 관련되어 있습니다.
장점과 단점
데이터는 최종 선입선출 방식으로 추가 및 삭제되므로 스택 기반 메모리 할당은 매우 단순하고 일반적으로 다음을 통해 할당되는 힙 기반 메모리 할당(동적 메모리 할당이라고도 함)보다 훨씬 빠릅니다.malloc
를 클릭합니다.[citation needed]
또 다른 기능은 함수가 종료될 때 스택 상의 메모리가 자동으로 매우 효율적으로 회수된다는 것입니다.이 기능은 데이터가 더 이상 [1]필요하지 않을 때 프로그래머에게 편리할 수 있습니다.(longjmp가 콜 전 포인트로 이동했을 경우에도 같은 내용이 적용됩니다.alloca
발생하였습니다.)그러나 데이터를 어떤 형태로든 보관해야 할 경우 함수를 종료하기 전에 데이터를 스택에서 힙으로 복사해야 합니다.따라서 스택 기반 할당은 현재 기능이 종료된 후 더 이상 필요하지 않은 임시 데이터 또는 데이터에 적합합니다.
스레드에 할당된 스택 크기는 일부 작은 CPU에서 몇 바이트만큼 작을 수 있습니다.사용 가능한 메모리보다 더 많은 메모리를 스택에 할당하면 스택 오버플로로 인해 크래시가 발생할 수 있습니다.이는 또한 이 기능을 사용하는 이유이기도 합니다.alloca
는,[2] 통상은 인라인 되지 않습니다.이러한 기능이 루프로 인라인 되어 있는 경우, 발신자는 예기치 않게 스택의 사용율이 증가해, 오버플로가 발생할 가능성이 높아집니다.
스택 베이스의 할당에 의해서도, 경미한 퍼포먼스의 문제가 발생할 가능성이 있습니다.그 때문에, 스택과 프레임의 양쪽 모두의 포인터를 관리할 필요가 있습니다(고정 사이즈의 스택프레임에서는, 어느쪽인가 용장합니다).이것은 보통 전화보다 훨씬 비용이 적게 든다.malloc
그리고.free
어쨌든.특히, 현재 함수가 할당하는 호출과 가변 길이의 로컬 데이터를 포함하는 블록을 모두 포함하는 경우, 현재 함수가 종료될 때까지 현재 스택프레임을 증가시키려는 할당의 시도와 스택프레임 내의 같은 위치에 가변 길이의 로컬 변수를 배치해야 하는 컴파일러의 필요성 사이에 충돌이 발생합니다.이 경합은 일반적으로 할당하는 각 콜에 대해 별도의 힙스토리지 체인을 작성함으로써 해결됩니다(https://code.woboq.org/gcc/libiberty/alloca.c.html) 참조).체인은 각 할당이 발생하는 스택의 깊이를 기록합니다.이 후 함수에서 할당하는 호출은 이 체인을 현재 스택의 깊이로 트리밍하여 최종적으로(즉각은 아니지만) 이 체인의 스토리지를 해방합니다.인수가 0인 할당 콜을 사용하여 메모리를 할당하지 않고 메모리 해방을 트리거할 수도 있습니다.alloc와 로컬 변수 스토리지 간의 이러한 충돌로 인해 alloc을 사용하는 것보다 alloc를 사용하는 것이 효율적이지 않을 수 있습니다.
시스템 인터페이스
Microsoft Windows와 마찬가지로 Unix와 유사한 많은 시스템도 다음과 같은 기능을 구현합니다.alloca
힙 기반과 유사한 방법으로 스택메모리를 동적으로 할당하기 위해malloc
컴파일러는 보통 가변 길이 배열의 [3]처리 방법과 마찬가지로 스택포인터를 조작하는 인라인 명령으로 변환합니다.메모리를 명시적으로 해방할 필요는 없지만 스택오버플로로 [4]인해 정의되지 않은 동작이 발생할 위험이 있습니다.이 함수는 32/V(1978)의 UNIX 시스템에 존재했지만 표준 C 또는 POSIX 표준의 일부가 아닙니다.
보다 안전한 버전의alloca
불렀다_malloca
는, 에러를 리포트하는 것으로, Microsoft Windows 에 존재합니다.그것은 의 사용이 필요하다._freea
.[5]gnulib는 동등한 인터페이스를 제공하지만 오버플로우에서 SEH 예외를 발생시키는 대신malloc
큰 사이즈가 [6]검출되었을 경우.유사한 기능은 수동 계정 및 크기 검사를 사용하여 에뮬레이트할 수 있습니다. 예를 들어,alloca_account
glibc로 [7]표시됩니다.
x86과 같은 일부 프로세서 패밀리는 현재 실행 중인 스레드의 스택을 조작하기 위한 특별한 명령을 가지고 있습니다.PowerPC나 MIPS 등의 다른 프로세서 패밀리는 명시적인 스택 지원을 하지 않고 통념에 의존하여 스택 관리를 운영체제의 Application Binary Interface(ABI; 응용 프로그램 바이너리 인터페이스)에 위임합니다.
자동 VLA
또, C버전 C99 이후에서는, 자동 VLA(가변장 배열)[8]라고 불리는 함수내에 자동적으로 배열을 작성할 수 있습니다.
무효 f(인트 점등하다) { 인트 b[점등하다]; // 자동 VLA - 이 어레이의 길이는 다음과 같이 설정됩니다. // 함수 호출/스택 생성 시간. 위해서 (인트 i = 0; i < > 점등하다; i++) b[i] = 1; // 이 함수의 끝에서 b[]는 스택프레임 내에 있으며, // 함수가 종료되면 사라지므로 free()에 대한 명시적인 호출은 필요하지 않습니다. }
「 」를 참조해 주세요.
레퍼런스
- ^ "Advantages of Alloca". The GNU C Library.
- ^ "Inline". Using the GNU Compiler Collection (GCC).
- ^ Linux 프로그래머 매뉴얼– 라이브러리 기능 –
- ^ "Why is the use of alloca() not considered good practice?". stackoverflow.com. Retrieved 2016-01-05.
- ^ "_malloca". Microsoft CRT Documentation.
- ^ "gnulib/malloca.h". GitHub. Retrieved 24 November 2019.
- ^ "glibc/include/alloca.h". Beren Minor's Mirrors. 23 November 2019.
- ^ "ISO C 99 Definition" (PDF). Retrieved 2022-04-10.