문제의 역사:
스택 메모리는 모든 주요 아키텍처에서 존재합니다. C 언어에서는 자동(로컬) 변수가 스택에 위치하여 동적 힙과 비교하여 메모리 할당 및 해제가 매우 빠릅니다.
문제:
스택의 사용은 크기로 제한되어 있으며, 자동 변수는 블록을 벗어날 때 자동으로 소멸하며, 스택 오버플로우(stack overflow)는 프로그램의 비정상 종료 또는 데이터 손상을 초래합니다.
해결책:
특별한 수정자 없이 함수 내에 선언된 로컬 변수는 스택에 배치됩니다. 이 자동 저장 영역은 함수에 들어갈 때 생성되고 나갈 때 파괴됩니다. 스택의 크기는 제한되어 있으며, 링크 옵션/시스템에서만 변경할 수 있습니다.
코드 예시:
#include <stdio.h> void foo() { int arr[100]; // 스택에 배치됨 for (int i = 0; i < 100; ++i) arr[i] = i; printf("첫 번째 요소: %d\n", arr[0]); } // foo를 벗어날 때 arr이 소멸됨
주요 특징:
주소를 통해 로컬 변수를 반환할 수 있습니까?
아니요, 함수에서 나갈 때 변수가 소멸되므로 결과적으로 "유령 포인터"가 생성되어 정의되지 않은 동작을 초래합니다.
int* bad() { int x = 42; return &x; // 오류: 반환된 포인터가 해제된 스택을 가리킴 }
스택에 큰 배열(예: 1MB)을 배치할 수 있습니까?
대부분의 시스템에서 스택은 제한적입니다(수십에서 수백 KB). 스택에 거대한 배열을 선언하려고 시도하면 스택 오버플로우가 발생합니다.
정적(static) 변수와 자동 변수의 배치에서 차이점은 무엇입니까?
정적 변수(함수 내에서도)는 정적 메모리 영역에 배치되며, 호출 사이에 초기화되지 않고, 자동 변수는 스택에 배치되어 블록을 벗어날 때 소멸됩니다.
계산을 위한 함수에서 스택에 8192*1024 double 배열을 할당했습니다. 프로그램은 Linux에서 실행 시 SIGSEGV를 받았고, 컴파일에서는 오류가 없었습니다.
장점:
단점:
대량의 버퍼 작업을 위해 malloc/free를 통한 동적 메모리 할당을 사용했습니다. 스택에는 작은 작업 변수를만 배치했습니다.
장점:
단점: