2014-07-23 6 views
2

은 이미 어느 정도 비슷한 질문 (why this code works in C)을 읽었습니다하지만 실제로 실제로 작업이 코드 조각 이유를 설명 도착하지 않습니다이 코드가 실제로 작동하는 이유는 무엇입니까?

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

typedef struct example 
{ 
    char length[2]; 
} STRUCT; 

int main (void) 
{ 
    STRUCT test; 
    strcpy(test.length, "********"); 
    puts(test.length); 
    return 0; 
} 

내가 그것을 컴파일 CodeBlocks를 사용하고, 그래서 I 디폴트로 여분의 별표를 저장하기 위해 문자열에 더 많은 공간을 할당한다고 생각합니다 ... 나는 정말로 모른다. 어쩌면 나는 운이 좋다, 그러나 그것을 실행할 때마다 그것은 작동한다.

위 예제에서 2의 배열에 2 개의 요소를 넣었습니다. 여기서 문자열은 처리 할 수있는 것보다 많은 공간을 사용하고 있습니다.

+1

http : //en.wikipedia.org/wiki/Buffer_overflow 그리고 네, 운이 좋습니다. 할당 한 범위를 벗어난 상태로 작성하는 것은 정의되지 않은 동작이므로 OS 충돌 (또는 더 심한 경우)에 이르기까지 모든 문제가 발생할 수 있습니다. –

+4

프로그램에 [* 정의되지 않은 동작 *]이 표시됩니다 (http : // en.wikipedia.org/wiki/Undefined_behavior) 부적절합니다. 달리기, 행운, 비강 악마 (http://www.catb.org/jargon/html/N/nasal-demons.html)를 얻는 것은 행운입니다. –

+1

정의되지 않은 동작에 오신 것을 환영합니다. 이것은 최악의 종류의 정의되지 않은 동작입니다. 코드가 작동합니다. 정말로 진절머리 나는 일이 일어날 때까지 수 년 동안 일할 것입니다. 때로는 CNN이나 slashdot에서 끝나기도합니다. – pm100

답변

1

행운입니다.

구조체는 2 바이트 길이로만 선언되지만 컴파일러 또는 런타임은 struct 이후 메모리 위치를 더 많이 할당하거나 신경 쓰지 않을 수도 있습니다. strcpystruct이며 결국 큰 컨텍스트에서 사용되는 경우 다른 메모리에 우선적으로 사용되는 일부 메모리를 무시하고 어떤 메모리 유형을 덮어 쓰고 그 메모리를 사용했는지에 따라 치명적인 오류가 발생합니다.

경우에 따라 프로그램이 종료되므로 운이 좋으면 아무도 손상된 메모리를 사용할 수 없습니다.

3

C는 배열 경계를 확인하지 않습니다. Ricky Mutschlechner가 언급 한 바와 같이 버퍼 오버 플로우와 정의되지 않은 동작을 초래합니다.

+0

그래, 내가 알기 론, 나는 아마도 이런 경우에 컴파일러가 도움이된다고 생각했다. –

+0

@matt_s - 아니요. – Soren

0

작성된 메모리 (할당되지 않은 메모리)가이 응용 프로그램의 다른 부분에서 사용되지 않았기 때문에 작동합니다. 나는 메모리 할당이 어떻게 작동하는지, 얼마나 큰 덩어리인지에 대해서는 자세히 모른다. 자세한 내용을 검색하기 만하면됩니다.

OS를 중단시키지 않지만 최악의 경우 세그멘테이션 오류가 발생합니다.

+0

기술적으로 UB이기 때문에 OS를 크래시 할 수 있습니다. –

+0

은 OS에 따라 다릅니다. 올드, 스몰, 임베디드 - 그들은 충돌 할 것이다 – pm100

+1

나는 OS에 의존한다고 동의한다. http://stackoverflow.com/questions/15646973/how-dangerous-is-it-to-access-an-array-out-of-bounds – nvd

1

이것은 예를 들어 정의되지 않은 동작 (의견에 언급 된대로)입니다.

구체적으로 이것이 작동하는 이유는 스택 정렬 때문일 가능성이 큽니다. 따라서 STRUCT test을 선언하면 컴파일러는 스택에 여분의 패딩을 추가하여 스택을 정렬하므로 test 다음에 여분의 사용되지 않는 공간이 생깁니다 (strcpy). 프로그램의 다른 부분은이 공간을 사용하지 않으므로 문제없이 작동한다는 착각을 불러 일으 킵니다.

0

테스트가 스택에 있기 때문에 스택이 오버 플로우되고 있습니다. 현재로서는 문제가되지 않을 수도 있지만 테스트와 함께 스택에 더 많은 변수를 선언하면 일부 문제가 발생할 수 있습니다.

+0

스택 오버플로는 다른 종류의 버그입니다. 당신은 "** 스택에 넘쳐 흐르고있다"고 말할 수도 있습니다. –

0

test.length 뒤에있는 스택 메모리에 쓰고 있습니다. 당신은 printf와 42를 인쇄하는 기대하지만, 변수 foo는 strcpy를 덮어 쓰기됩니다

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

typedef struct example 
{ 
    char length[2]; 
} STRUCT; 

int main (void) 
{ 
    STRUCT test; 
    unsigned int foo = 42; 
    strcpy(test.length, "********"); 
    puts(test.length); 
    printf("%u", foo); 
    return 0; 
} 

: 더 나은 문제를 설명하기 위해, 나는 당신의 코드에 두 줄을 추가했다. 실제 출력은 gcc와 같이 다음과 같습니다 (here 테스트 가능) :

******** 
707406378 
관련 문제