C함수와 배열

배열 경계와 off-by-one

`0`부터 시작하는 인덱스와 배열 크기 경계를 잘못 읽어 생기는 off-by-one 오류를 어떻게 피할지 정리합니다.

마지막 수정 2026년 3월 22일

기본 패턴

c
int values[4] = {10, 20, 30, 40};

for (size_t i = 0; i < 4; i += 1) {
    printf("%d\n", values[i]);
}

설명

  • C 배열은 인덱스가 0부터 시작하므로 길이가 4인 배열의 마지막 유효 인덱스는 3입니다. 이 단순한 사실이 실제로는 수많은 메모리 오류의 출발점이 됩니다.
  • off-by-one은 반복문 종료 조건을 하나 잘못 써서 한 칸 덜 읽거나 한 칸 더 읽는 실수입니다. 특히 <= size< size 차이가 대표적입니다.
  • C에서는 경계를 넘어선 접근이 자동으로 막히지 않습니다. 즉 실수해도 곧바로 에러가 나지 않고, 조용히 다른 메모리를 덮어쓰거나 읽으면서 정의되지 않은 동작으로 이어질 수 있습니다.
  • 그래서 배열을 다룰 때 중요한 것은 문법보다 "길이와 인덱스를 항상 함께 본다"는 습관입니다. 배열 길이를 별도 변수로 두고, 반복문 조건을 일관되게 유지하는 편이 좋습니다.
  • 이 감각은 문자열, 동적 메모리, 포인터 산술로 그대로 이어집니다. C에서 메모리 안전성의 기본은 결국 경계 감각이라고 봐도 됩니다.

빠른 정리

표현의미
길이 n 배열유효 인덱스는 0부터 n - 1까지
i < n가장 흔한 안전한 반복 조건
i <= n한 칸 초과 위험
핵심 습관길이와 인덱스를 함께 관리

주의할 점

경계를 넘는 배열 접근은 "오류 메시지"보다 "조용한 메모리 오염"으로 나타나는 경우가 많습니다. 반복문이 맞아 보여도 마지막 조건을 한 번 더 의심하는 습관이 중요합니다.

참고 링크

1 sources