2017-02-08 7 views
3

: 선언이 x는 너무 큰 것에 대해 충돌을가는 경우에 당신이 결코 를 알 수 없기 때문에대형 VLA 다른 스레드에서 다른 사람의 의견을 바탕으로 오버 플로우

블라스, 그들은 해결보다 더 많은 문제를 소개합니다 스택.

sizeof(a) 스택 너무 길기 때문에이 코드는 오버플로 :

#include <stdio.h> 
#include <stdlib.h> 

int main(void) 
{ 
    int n = 100000000; 
    int a[4][n]; 

    printf("%zu\n", sizeof(a)); 

    return 0; 
} 

하지만이 일 수 없습니다 sizeof(a) 8 (내 컴퓨터에있는 포인터의 크기) 때문에 :

#include <stdio.h> 
#include <stdlib.h> 

int main(void) 
{ 
    int n = 100000000; 
    int (*a)[n]; 

    printf("%zu\n", sizeof(a)); 
    a = malloc(sizeof(*a) * 4); 
    free(a); 
    return 0; 
} 

제 가정은 정확합니까?

sizeof 개체를 기반으로 VLA 사용이 위험한 지 아닌지 (넘칠 수 있음)를 결정할 수 있습니까?

+2

'int (* a) [n]; '은 (는) VLA가 아닙니다. VLA에 대한 포인터입니다. – chux

+1

왜 sizeof (* a)에 4를 곱합니까? 100000000x4 배열을 만들고 있습니까? – dasblinkenlight

+1

게다가 chux가 지적한 것처럼 'int (* a) [n]'은 VLA에 대한 포인터이며 VLA에 대한 포인터가 아닙니다. – dasblinkenlight

답변

4

int (*a)[n];은 VLA가 아니라 VLA에 대한 포인터입니다. 따라서 OP 2 예제는 충분히 근접한 비교가 아닙니다. @M.M로서


은 스택 오버 플로우를 방지하는 임의의 자동 할당에 문제가 주석. 재귀는 스택을 지나치게 소비 할 수 있습니다. 로컬 큰 변수는 너무 많이 스택을 소비 할 수 있습니다.

VLA는 단순히 심각하게 사용되는 것 중 하나 일뿐입니다. 당신은 결코 선언이 x는 스택에 대한 너무 큰 것에 대해 충돌 것입니다 알고하지 않기 때문에

// Qualified use of VLA 
int len = snprintf(NULL, 0 "%d", some_int); 
assert(len > 0); 
char vla_good[len+1]; 
len = snprintf(vla_good, len+1, "%d", some_int); 

// Unqualified 
int x; 
scanf("%d", &x); 
char vla_bad[x]; // who knowns what x may be, did scanf() even work? 

블라스는, 그들이 해결보다 더 많은 문제를 소개합니다.

VLA의 사용이 위험한 지 확인할 수 있습니까?

작업에 적합한 도구를 사용하십시오. 일반적으로 최악의 경우 작은 고정 크기 배열이 사용됩니다. VLA는 사용이 제한적입니다. 견고한 코드는 VLA를 선언하기 전에 배열 요소 수를 어리석게 만들지 않도록 보장합니다.

C99에서 사용할 수있는 VLA는 C11에서 선택적으로 지원된다는 점에 유의하십시오.

VLA는 나쁘지 않습니다. 그들은 just drawn that way입니다.