2014-07-16 2 views
1

나는 다음과 같은 코드를 가지고 :이 코드는 컴파일시 오류가 발생하는 기대버퍼 할당

void function(char *str) 
{ 
    int i; 
    char buffer[strlen(str) + 1]; 

    strcpy(buffer, str); 
    buffer[strlen(str)] = '\0'; 

    printf("Buffer: %s\n", buffer); 
} 

의 '버퍼'스택에 할당되는로를 따라 런타임을하고있다 길이 (strlen() 기준). 그러나 GCC에서는 컴파일이 통과됩니다. 이게 어떻게 작동합니까? 버퍼가 동적으로 할당되었거나 여전히 스택 로컬 인 경우 할당 된 크기는 얼마입니까?

+4

유효한 C99이며 예, 계산 된 크기에 따라 스택에 할당됩니다. –

+0

@mafso 왜 정의되지 않은 동작이 발생할 것이라고 말합니까? – dragosht

+2

두 가지 언어로 태그를 추가했습니다. 이것은 (현대) C에서는 유효하지만 C++에서는 유효하지 않습니다. 어느 쪽을 사용하고 있습니까? –

답변

2

C99는 가변 길이 배열을 허용합니다. GCC가 가변 길이 배열을 확장으로 허용하기 때문에 C99에서 코드를 컴파일해도 오류가 발생하지 않습니다.

6.19 Arrays of Variable Length

: 확장 GCC는 C90 모드와 ++ C에서 그들을 수용으로

가변 길이 자동 배열은 ISO C99에서 허용하고 된다.

1

함수를 분해하여 쉽게이를 확인할 수 : 어셈블리의 관련 부분이 여기 어쨌든 sub %eax,%esp입니다

$ objdump -S <yourprogram> 

... 
void function(char *str) 
{ 
    4011a0: 55      push %ebp 
    4011a1: 89 e5     mov %esp,%ebp 
    4011a3: 53      push %ebx 
    4011a4: 83 ec 24    sub $0x24,%esp 
    4011a7: 89 e0     mov %esp,%eax 
    4011a9: 89 c3     mov %eax,%ebx 
    int i; 
    char buffer[strlen(str) + 1]; 
    4011ab: 8b 45 08    mov 0x8(%ebp),%eax 
    4011ae: 89 04 24    mov %eax,(%esp) 
    4011b1: e8 42 01 00 00   call 4012f8 <_strlen> 
    4011b6: 83 c0 01    add $0x1,%eax 
    4011b9: 89 c2     mov %eax,%edx 
    4011bb: 83 ea 01    sub $0x1,%edx 
    4011be: 89 55 f4    mov %edx,-0xc(%ebp) 
    4011c1: ba 10 00 00 00   mov $0x10,%edx 
    4011c6: 83 ea 01    sub $0x1,%edx 
    4011c9: 01 d0     add %edx,%eax 
    4011cb: b9 10 00 00 00   mov $0x10,%ecx 
    4011d0: ba 00 00 00 00   mov $0x0,%edx 
    4011d5: f7 f1     div %ecx 
    4011d7: 6b c0 10    imul $0x10,%eax,%eax 
    4011da: e8 6d 00 00 00   call 40124c <___chkstk_ms> 
    4011df: 29 c4     sub %eax,%esp 
    4011e1: 8d 44 24 08    lea 0x8(%esp),%eax 
    4011e5: 83 c0 00    add $0x0,%eax 
    4011e8: 89 45 f0    mov %eax,-0x10(%ebp) 
.... 

. 이것은 버퍼 공간을 얻기 위해 이전에 반환 된 strlen에 기반하여 스택이 확장되었음을 보여줍니다.