가변 길이 배열

Variable-length array

컴퓨터 프로그래밍에서 가변 크기 또는 런타임 크기라고도 불리는 가변 길이 배열(VLA)은 길이가 (컴파일 시간 대신) 런타임에 결정되는 배열 데이터 구조다.[1]C에서 VLA는 값에 따라 달라지는 가변적으로 수정된 유형을 가지고 있다고 한다(종속형 참조).null

VLA의 주요 목적은 수치 알고리즘의 프로그래밍을 단순화하는 것이다.null

VLA를 지원하는 프로그래밍 언어로는 Ada, Algol 68(불가연성 행의 경우), APL, C99(이후 C11에서 조건부 기능으로 강등되었지만, 일부 플랫폼에서는 이 기능을 지원할 필요가 없다.[2][3]alloca()또는 유사한 기능) 및 C#(안전하지 않은 모드 스택 할당 배열로), COBOL, Fortran 90, J 및 Object Pascal(FPC를 사용하는 볼랜드 델파이라자러스에서 사용되는 언어)과 C#(안전하지 않은 모드 스택 할당 배열로, COBOL, Fortran 90, J, Object Pascal.null

기억력

할당

  • GNU C 컴파일러는 VLA에 메모리를 할당하고 스택자동 스토리지 기간을 지정한다.[4]이는 힙 할당에 비해 빠르고 간편한 옵션이며 대부분의 컴파일러가 사용한다.
  • 또한 VLA는 에 할당되고 이 블록에 대한 포인터를 사용하여 내부적으로 액세스할 수 있다.

실행

C99

다음 C99 함수는 지정된 크기의 가변 길이 배열을 할당하고 부동 소수점 값으로 채운 다음 처리를 위해 다른 함수에 전달한다.배열은 자동변수로 선언되기 때문에 그 수명은 다음과 같은 경우에 끝난다.read_and_process()돌아온다null

둥둥 뜨다 read_and_process(인트로 n) {     둥둥 뜨다 발스[n];      을 위해 (인트로 i = 0; i < n; ++i)         발스[i] = read_val();      돌아오다 과정(n, 발스); } 

C99에서 길이 매개변수는 함수 호출에서 가변 길이 배열 매개변수 앞에 와야 한다.[1]C11에서 a__STDC_NO_VLA__VLA가 지원되지 않는 경우 매크로가 정의된다.[5]GCC는 C99 이전에 확장자로 VLA를 사용했는데, C++ 사투리로도 확장된다.null

리누스 토발즈는 더 낮은 품질의 조립 코드를 생성하기 때문에 미리 결정된 작은 크기의 어레이에 VLA를 사용하는 것에 대해 과거에 불쾌감을 표시했다.[6] 리눅스 4.20 커널로 리눅스 커널은 사실상 VLA가 없다.[7]null

C11이 VLA에 대한 크기 제한을 명시적으로 지정하지는 않지만, 일부 판독치는 다른 모든 개체(예: SIZE_MAX 바이트)와 동일한 최대 크기를 가져야 한다고 생각한다.[8]단, 이 판독은 SIZE_MAX보다 작은 규모의 많은 수의 순서인 4KiB의 일반적인 스택 가드 페이지 크기와 같이 환경 및 플랫폼 제한의 넓은 맥락에서 이해해야 한다.

어레이에 대한 포인터를 사용하면 동적 스토리지와 함께 VLA와 같은 구문을 사용할 수 있다.null

둥둥 뜨다 read_and_process(인트로 n) {     둥둥 뜨다 (*발스)[n] = 만록의(의 크기(둥둥 뜨다[n]));      을 위해 (인트로 i = 0; i < n; ++i)         (*발스)[i] = read_val();      둥둥 뜨다 되받아치다 = 과정(n, *발스);          무료의(발스);          돌아오다 되받아치다; } 

에이다

다음은 에이다님에서도 같은 예다.Ada 어레이는 그 한계를 가지고 있으므로, 프로세스 함수에 길이를 넘길 필요가 없다.null

타자를 치다 Vals_Type 이다 배열하다 (긍정적인 범위 <>)  플로트;  기능을 하다 Read_And_Process (N :정수) 돌아오다 플로트 이다    발스 : Vals_Type (1 .. N); 시작되다    을 위해 I  1 .. N 고리를 틀다       발스 (I) := Read_Val;    종지부를 찍다 고리를 틀다;    돌아오다 과정 (발스); 종지부를 찍다 Read_And_Process; 

포트란90번길

등가 Fortran 90 함수는

기능을 하다read_and_process(n) 결과(o)     정수의,의도적인()::n     진짜::o      진짜,치수(n)::발스     정수의::i      하다i = 1,n        발스(i) = read_val()     끝내다     o = 과정(발스) 끝 함수read_and_process 

컴파일 시 절차 인터페이스 점검의 Fortran 90 기능을 이용할 때, 한편, 기능이 Fortran 90 이전의 통화 인터페이스를 사용하는 경우, (외부) 기능을 먼저 선언해야 하며, 배열 길이는 (C와 같이) 인수로 명시적으로 통과해야 한다.

기능을 하다read_and_process(n) 결과(o)     정수의,의도적인()::n     진짜::o      진짜,치수(n)::발스     진짜::read_val, 과정     정수의::i      하다i = 1,n        발스(i) = read_val()     끝내다     o = 과정(발스,n) 끝 함수read_and_process 

코볼

다음 COBOL 파편은 가변 길이 레코드 배열을 선언한다.DEPT-PERSON의 값으로 지정된 길이(구성원 수)를 가지는 것PEOPLE-CNT:

데이터 나누기. 작업-스토리지 섹션. 01  뎁트-피플.     05  피플-CNT          PIC S9(4) 이진수.     05  뎁트-Person         일어나다 0  20 시대 부수적인 켜기 피플-CNT.         10  Person-이름     PIC X(20).         10  개인-임금     PIC S9(7)V99 PACKED-DECIMAL. 

COBOL VLA는 여기에서 언급된 다른 언어와 달리 COBOL은 최대 배열 크기를 지정하기 위해 COBOL이 필요하기 때문에 안전하다.DEPT-PERSON의 가치에 관계없이 20개 이상의 품목을 가질 수 없다.PEOPLE-CNT.

C#

다음 C# 파편은 가변 길이 정수 배열을 선언한다.C# 버전 7.2 이전에 어레이에 대한 포인터가 필요하므로 "안전하지 않은" 컨텍스트가 필요하다."안전하지 않은" 키워드는 이 코드를 포함하는 어셈블리를 안전하지 않은 것으로 표시하도록 요구한다.null

안전하지 않은 공허하게 하다 SelectStackBasedArrayUnsafe(인트로 사이즈를 맞추다) {     인트로 *파레이 = 겹겹이 쌓다 인트로[사이즈를 맞추다];     파레이[0] = 123; } 

C# 버전 7.2 이상에서는 "안전하지 않은" 키워드 없이 스팬 기능을 사용하여 어레이를 할당할 수 있다.[9]null

공허하게 하다 SelectStackBasedArraySafe(인트로 사이즈를 맞추다) {     스판<인트로> 스택 어레이 = 겹겹이 쌓다 인트로[사이즈를 맞추다];     스택 어레이[0] = 123; } 

객체 파스칼

이 언어에서는 동적 배열이라고 한다.그러한 변수의 선언은 정적 배열의 선언과 유사하지만 그 크기를 명시하지 않는다.배열의 크기는 그 사용 시점에 주어진다.null

프로그램 CreateDynamicArrayOfNumbers(크기: 정수); 시합을 하다   숫자 배열: 배열하다  롱워드; 시작되다   SetLength(숫자 배열, 크기);   숫자 배열[0] := 2020; 종지부를 찍다. 

동적 배열의 내용을 제거하려면 0의 크기를 할당하면 된다.null

... SetLength(숫자 배열, 0); ... 

참조

  1. ^ a b "Variable Length Arrays". Archived from the original on 2018-01-26.
  2. ^ "Variable Length – Using the GNU Compiler Collection (GCC)".
  3. ^ ISO 9899:2011 프로그래밍 언어 – C 6.7.6.2 4
  4. ^ "Code Gen Options - The GNU Fortran Compiler".
  5. ^ C11 표준 § 6.10.8.3 (n1570.pdf)
  6. ^ "LKML: Linus Torvalds: Re: VLA removal (was Re: [RFC 2/2] lustre: use VLA_SAFE)". lkml.org.
  7. ^ "The Linux Kernel Is Now VLA-Free: A Win For Security, Less Overhead & Better For Clang - Phoronix". www.phoronix.com.
  8. ^ C11 표준 제6.5.3.4조 및 제7.20.3조 (n1570.pdf)
  9. ^ "stackalloc operator (C# reference)". Microsoft.