본문 바로가기

프로그래밍 언어/C 언어

C언어: 변수를 배열의 크기로 지정할 수 있을까?

가변 길이 배열 (VLA)

  길이가 정해져있지 않고 변할 수 있는 배열을 '가변 길이 배열'이라고 합니다. 영어로는 Variable Length Array라고 하며, 짧게 VLA라고 부르기도 합니다.

 

#include <stdio.h>

int main(void){
    int length;
    scanf("%d", &length);
    int array[length];

    for(int i=0; i<length; i++){
        array[i] = i;
        printf("%d ", array[i]);
    }
    return 0;
}

 

  가변 길이 배열을 시험해볼 수 있는 간단한 C언어 코드입니다. 변수 length의 값을 지정해주지 않은 채 배열 array를 선언하고, length의 값은 런타임 때 사용자가 직접 정해줍니다. 런타임 때 length가 정해지면, Line 8 ~ 11의 for문에 의해 배열 array가 채워지고, 그 값들이 출력되죠. 출력 결과는 다음과 같습니다.

 

# 입력값 '5'의 출력 결과
0 1 2 3 4

# 입력값 '8'의 출력 결과
0 1 2 3 4 5 6 7

 

  이렇듯, C언어에서 가변 길이 배열(VLA)을 선언하고 이용하는 것이 가능합니다. 하지만 항상 가능한 것은 아닙니다. 다음 섹션에서 어떠한 경우들에 C언어에서 가변 길이 배열이 이용 가능한지 알아봅시다!

 


C언어의 가변 길이 배열

  C언어에서 가변 길이 배열이 지원되는가 지원되지 않는가는, C언어의 버전에 따라 다르며 C99 이후 버전들에서는 가능합니다. C89/C90과 같이 더 이전에 나온 버전에서는 가변 길이 배열이 지원되지 않고, C99 부터 이용이 가능합니다. 이후 버전인 C11, C17에서는 가변 길이 배열을 선택적으로 도입할 수 있어, 컴파일러의 종류에 따라 지원되지 않을 수도 있습니다. C11 컴파일러가 VLA를 지원하지 않으려면, __STDC_NO_VLA__ 매크로를 정의해야 합니다. 정리하면, 아래 표와 같습니다.

 

C언어 Version 가변 길이 배열 (VLA) 지원 여부
C99 전    (Ex. C89/C90) X
C99 O
C99 후    (Ex. C11,  C12) △   (__STDC_NO_VLA__ 매크로에 따라 다름)

 

  C99 전, 배열의 크기는 컴파일할 때만 정해줄 수 있었습니다. VLA가 도입되면서 배열의 크기는 런타임 때 정할 수 있게 되었고, 훨씬 간결한 코드 작성이 가능해졌습니다. 만약 가변 길이 배열을 사용하는데, 변수를 배열의 크기로 지정할 수 없다는 에러가 뜬다면, 가장 먼저 C언어 버전부터 확인해보세요! 컴파일러의 C언어 버전이 C99 보다 전에 나온 버전이라면, 가변 길이 배열을 지원해주지 않아 에러가 뜨는 것일 수도 있습니다. 또한 C11 이후 버전인데 지원되지 않는다면, __STDC_NO_VLA__ 매크로에 의해 VLA 기능이 꺼져있는 것은 아닌지 확인해보세요.


VLA와 malloc 중에 어느 것을 사용할까?

  C언어를 사용할 때 가장 번거로운 작업 중 하나가 바로 memory management, 즉 메모리를 관리하는 것입니다. 런타임 때, 동적으로 메모리를 할당하는 기능으로 'malloc'이 있는데, malloc은 'heap'이라는 곳의 메모리를 할당해줍니다. Heap에 할당한 메모리는 사용이 끝날 때 'free'를 해줘야하기 때문에 malloc을 많이 하다보면 머리가 아파지죠. 따라서 malloc으로 배열을 위한 메모리를 할당하면 메모리 관리 때문에 코드가 복잡해지기 마련입니다.

  VLA (가변 길이 배열)의 장점 중 하나가 이러한 메모리 관리를 자동으로 해준다는 것입니다. VLA를 위한 메모리는 malloc과는 달리 'stack'이라는 곳의 메모리를 할당받는데, stack는 block scope를 가지므로 코드가 끝날 때 할당받았던 메모리가 자동으로 지워집니다. 따라서 메모리 관리를 따로 해주지 않아도 되어 굉장히 편리합니다. 물론 이러한 특징이 단점이 되기도 하는데, stack은 heap보다 크기가 훨씬 작기 때문에 stack의 크기를 넘어가버리면 에러가 뜨게 되므로 너무 많은 메모리를 할당하지 않도록 주의해야 합니다.

  결론적으로, 배열에 넣어줄 정보가 과하게 많지 않다면 VLA를 쓰는 것을 추천드립니다. Malloc으로 할당한 메모리를 free 해주지 않아 에러가 생기는 일을 방지해주기 때문이죠. 코드도 훨씬 간단해지고, 이해하기 쉬워집니다. 다만 C언어의 버전이 다르면 VLA가 지원되지 않을 수도 있다는 것만 주의해주시면 되겠습니다!

반응형