1. Visual C++ '가변 길이 배열' 사용할 수 없다.
C89 또는 C90 표준에 적용된 C 컴파일러는 배열을 사용해 변수를 선언할 때 아래와 같이 배열 길이를 상수로 사용해야 한다.
int data[5] ;
즉, 다음과 같이 사용하면 오류가 발생한다.
int size = 5 ;
int data[size] ;
하지만 C99 표준 문법에 위와 같은 표현이 사용될 수 있도록 적용되었고,
이를 '가변 길이 배열' (Variable-Length Array)이라고 부른다.
C11 버전에서는 VLA 지원은 필수가 아니다.
다시 말해 C11이 포함된 Visual C++도 C99 표준이 전부 적용된 것이 아니기 때문에
Visual Studio 2017에서 '가변 길이 배열' 또한 컴파일러에 따라 지원 여부가 달라진다.
2. GCC 계열, Prime Editor 에서는 '가변 길이 배열'을 사용할 수 있다.
리눅스나 유닉스 운영체제에서 많이 사용하는 gcc 계열의 컴파일러는 '가변 길이 배열' 표준안이 채택되어 사용이 가능하다.
3. malloc vs VLA
가변 길이 배열(Variable-Length Array)은 배열의 크기를 컴파일 타임에 정하지 않고 실행 타임에 정할 수 있도록 하는 기능이다.
malloc 함수와 VLA를 비교하면 다음과 같다.
malloc은 메모리 수동 관리, VLA는 자동 관리
C11, C++17 에서는 필수 지원이 아님
VLA는 편리하지만 큰 크기의 배열을 사용할 때에는 부적합
C99 에서는 아래의 기능을 제공한다.
int input_array_size(int size){
int array[size];
....
return 0;
}
해당 기능을 지원하지 않는 C 버전이라면 아래와 같이 malloc을 이용하여 위 기능을 구현할 수 있다.
하지만 위 기능을 사용한다면 더욱 편리하게 구현이 가능하다.
int * array;
array = malloc(size * sizeof(int));
4. 그렇다면 VLA를 반드시 사용해야 할까
malloc을 통해 동적 배열을 구현하는 것과 VLA를 사용하는 것은 매우 다르다.
차이점은 다음과 같다.
malloc을 통해 구현하는 것은 메모리를 수동으로 관리해야 한다.
해당 변수의 사용이 종료된다면 free를 이용하여 해제해야 하며, 이를 잊어버리거나 메모리 해제를 여러 번 할 때 문제가 발생한다.
VLA를 이용하여 구현하는 것은 아무것도 해제할 필요가 없다는 장점이 있다.
위 차이점만 본다면 VLA를 이용해야만 한다. 하지만 VLA에는 다음과 같은 문제점이 존재한다.
1. 할당 영역의 문제
malloc을 통해 생성된 배열은 heap 영역에 저장되는 반면,
VLA를 이용해 생성된 배열은 스택 영역에 할당된다.
할당 영역에서 큰 차이를 보인다. 일반적으로 스택보다 힙에서 더 많은 메모리를 사용이 가능하다.
이 차이로 인해 크기가 큰 배열을 다룰 때에는 malloc을 이용하는게 더 좋다.
VLA를 사용하게 된다면 스택 오버플로우 위험성이 커지므로 유의해야 한다.
2. 사용 범위의 문제
VLA 배열은 선언된 범위 내에서만 유효
malloc은 free를 호출할 때까지 프로그램 모든 곳에서 사용이 가능
참조1 C 언어 표준에 대한 이야기 - 2 : 네이버 블로그 (naver.com)
참조 2 [C언어] 가변 길이 배열(Variable-length Array)를 사용할 때 — 개발자스러운 블로그 (tistory.com)