0Pricing
C Academy · 강의

스택 오버플로 방지하기

재귀의 깊이를 제한해 보세요.

스택 오버플로 방지하기은(는) CoddyKit의 무료 C Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 C Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. C Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

스택 오버플로란 무엇인가요

호출 스택의 크기는 제한되어 있습니다. 각 함수 호출은 매개변수와 지역 변수를 저장하기 위해 스택의 일부를 사용합니다.

재귀가 너무 깊어지면 스택이 가득 차고 프로그램이 스택 오버플로로 비정상 종료됩니다.

기저 사례 누락

가장 흔한 원인은 절대 도달하지 않는 기저 사례입니다. 이 경우 실행이 영원히 계속되다가 스택 오버플로가 발생합니다.

이런 종류의 함수는 실행하지 말고, 왜 실패하는지 살펴보십시오.

int broken(int n) {
    /* no base case: never stops */
    return broken(n + 1);
}

줄어들지 않는 인수

기저 사례가 있더라도 인수는 기저 사례를 향해 변해야 합니다. 여기서는 n이 증가하므로 0에 도달하지 않습니다.

각 호출이 종료 조건에 더 가까워지는지 항상 확인하십시오.

int oops(int n) {
    if (n == 0) return 0;
    return oops(n + 1); /* wrong direction */
}

올바르게 수정한 버전

변화 방향을 바로잡으면 함수가 종료됩니다. 이제 n이 기저 사례인 0을 향해 감소합니다.

#include <stdio.h>

int good(int n) {
    if (n == 0) return 0;
    return n + good(n - 1);
}

int main(void) {
    printf("%d\n", good(10));
    return 0;
}

깊이 제한은 실제로 존재합니다

올바른 재귀라도 매우 깊어지면 오버플로가 발생할 수 있습니다. 함수를 수백만 단계 깊이로 호출하면 스택을 초과할 수 있으며, 스택 크기는 보통 몇 메가바이트에 불과합니다.

깊이가 매우 큰 경우에는 반복을 우선 사용하십시오.

깊은 재귀를 반복문으로 바꾸기

재귀 깊이가 입력 크기에 따라 증가한다면 반복문으로 바꾸십시오. 이렇게 하면 수천 개의 프레임이 쌓이는 것을 방지할 수 있습니다.

아래 반복문은 일정한 메모리만 사용하면서 큰 n에 대해 1부터 n까지의 합을 안전하게 계산합니다.

#include <stdio.h>

int main(void) {
    long total = 0;
    for (int i = 1; i <= 1000000; i++)
        total += i;
    printf("%ld\n", total);
    return 0;
}

분할 정복으로 깊이 줄이기

작업을 절반씩 나누면 깊이를 작게 유지할 수 있습니다. 범위를 절반씩 나누어 합을 구하면 깊이는 선형이 아니라 크기의 로그에 비례하여 증가합니다.

long range_sum(int lo, int hi) {
    if (lo == hi) return lo;
    int mid = (lo + hi) / 2;
    return range_sum(lo, mid) + range_sum(mid + 1, hi);
}

큰 지역 배열에 주의하기

큰 지역 변수는 각 프레임을 무겁게 만들므로 스택이 더 빠르게 가득 찹니다.

재귀 함수 안에서 큰 배열을 선언하지 말고, 포인터를 전달하거나 힙을 사용하십시오.

void heavy(int n) {
    int buffer[10000]; /* big frame each call */
    if (n == 0) return;
    heavy(n - 1);
}

누적 변수 사용하기

현재까지의 합을 누적 변수로 전달하면 각 프레임을 작게 유지할 수 있고 재귀가 꼬리 재귀 형태가 됩니다.

그러면 일부 컴파일러가 하나의 프레임을 재사용할 수 있습니다.

#include <stdio.h>

long sum_acc(int n, long acc) {
    if (n == 0) return acc;
    return sum_acc(n - 1, acc + n);
}

int main(void) {
    printf("%ld\n", sum_acc(100, 0));
    return 0;
}

안전 점검 목록

재귀 함수를 신뢰하고 사용하기 전에 다음을 확인하십시오.

1. 기저 사례가 있나요?
2. 모든 호출이 기저 사례를 향해 진행되나요?
3. 큰 입력에서 깊이가 매우 커질 수 있나요?

깊이가 폭발적으로 증가할 수 있다면 대신 반복문을 사용하십시오.

작은 입력으로 테스트하기

재귀는 항상 손으로 확인할 수 있는 아주 작은 입력으로 먼저 테스트하십시오.

작은 경우가 올바르게 작동하고 깊이가 제한되어 있다면 안심하고 규모를 키울 수 있습니다.

빠른 확인

가장 안전한 수정 방법을 찾아보십시오.

요약

스택 오버플로는 재귀가 너무 깊어지거나 멈추지 않을 때 발생합니다. 항상 도달 가능한 기저 사례를 제공하고, 호출마다 인수를 줄이며, 프레임을 가볍게 유지하십시오. 깊이가 입력 크기에 따라 증가할 수 있다면 반복으로 바꾸십시오.

자주 묻는 질문

“스택 오버플로 방지하기” 강의는 무료인가요?

네 — “스택 오버플로 방지하기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 C Academy 강의 전체를 잠금 해제할 수 있습니다. C Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“스택 오버플로 방지하기”에서 뭘 배우나요?

재귀의 깊이를 제한해 보세요. 브라우저에서 직접 실행하는 실습 코드로 C Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

C Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 C Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.

“스택 오버플로 방지하기” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 C Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 C Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 재귀가 작동하는 방식
  2. 고전적인 재귀 문제
  3. 재귀와 반복 비교
  4. 스택 오버플로 방지하기
← C Academy(으)로 돌아가기