SW/C

[VLA] Variable-length Array, 가변 길이 배열

Gangdor 2021. 9. 3. 14:31
반응형

VLA는 가변 길이 배열이다. 즉, 변수로 런타임중에 배열의 길이를 정할 수 있다는 말이다. 그 말은 즉, 사용자에게 Input을 받고 그 변수로 배열을 지정할 수도 있다는 말이다.

통상 우리가 알고 있는 배열은 상수로 길이가 지정되어 있고 컴파일중에 메모리 stack 영역에 할당이 된다고 알고 있다.

int arr[5]; //상수로 지정한 배열arr

int i;
scanf("%d", &i);
int arr2[i]; //VLA

C99부터 지원되는 VLA는 위의 코드처럼 사용자로부터 input받은 변수로도 배열을 지정할 수 있다. 기존에는 이러한 것이 불가하여 malloc, calloc과 같은 동적메모리 할당을 사용했는데 그럴 필요가 없다니... 너무 좋지 않은가? 그러나 꼭 그렇지만은 않다.

 

VLA의 특성과 장점

VLA의 특성부터 알아보자. VLA는 우선 기존의 상수배열 선언처럼 stack메모리에서 관리된다. C99부터 정식 지원으로 되어있다. 또한 compiler마다 이를 허용하기도 하고 하지 않기도 한다. stack 메모리에서 관리된다는 것은 사용자에 의해 할당하고 해제할 필요가 없이 자동으로 관리된다는 것을 의미한다. 즉, free()처럼 우리가 메모리를 따로 해제할 필요가 없다는 것이다. 때문에 사용자의 관리 미흡으로 인한 메모리 누수도 없을 것이다. 그럼 동적메모리 할당을 귀찮게 해줄 필요도 없고 너무 좋은 VLA만 사용하면 되지 않을까? 그러나 VLA는 치명적 단점이 있다. 무엇일까?

 

VLA의 치명적 단점

VLA는 기본적으로 stack영역에서 관리된다고 알아보았다. stack영역은 heap영역보다 접근 속도도 빠르지만 공간의 크기가 heap영역보다는 작다. 따라서 VLA는 stack overflow라는 치명적인 위험성을 내제하고 있다. 위의 예제로 돌아가

사용자에게 입력받은 input의 값이 stack메모리의 크기보다 큰 값을 받았다고 하자. 임베디드 시스템에서는 stack 영역의 크기는 한정적이기 때문에 충분히 가능성이 있는 이야기이다. 해킹이나 error로 인해 input으로 굉장히 큰 값을 입력받았고 그 크기의 메모리로 VLA 할당을 한다면? 당연히 stack이 터질 것이다. 이러한 불확실성은 매우 risky하다. 때문에 컴파일러 마다 VLA를 지원하기도 하고 하지 않기도 하는 것이다. 비주얼스튜디오는 VLA를 지원하지 않는다. C++도 VLA를 지원하지 않는다. stack overflow의 위험성 때문이리라. 따라서 큰 크기의 메모리할당이 필요할 시에는 heap영역에서 동적메모리 할당으로 관리해주는 것이 좋다.

반응형