2010-04-27 2 views
0

이 코드를 살펴보십시오. 첫 번째 변수에는 1 바이트를 할당하고 두 번째 변수에는 다른 바이트를 할당합니다. 그러나 컴파일러가 더 많은 것을 할당하는 것처럼 보입니다 (또는 뭔가 빠졌습니다). 프로그램은 길이가 1 바이트 이상이더라도 두 문자열 모두를 출력합니다.c : 메모리 할당 (현재 진행 중)

void main() { 
    char* some1 = malloc(1); 
    sprintf(some1,"cool"); 
    char* some2 = malloc(1); 
    sprintf(some2,"face"); 
    printf("%s ",some1); 
    printf("%s\n",some2); 
} 

메모리를 할당 할 때 어떤 일이 벌어지고 있는지 조명 해줄 수 있습니까?

+2

그건 그렇고, 내가 당신이라고 생각하는 것을 말하는다면 그것은 트롤 페이스가 아니라 쿨 페이스입니다. – GManNickG

+0

'main()'은 어떤 타입을 반환합니까? 나는 당신에게 힌트를 주겠다. 그것은'void'가 아니라'int'를 반환한다. –

답변

7

정의되지 않은 동작이 호출됩니다. 당신이 기대할 수있는 것들을 포함하여,이 시점에서 무엇이든 일어날 수 있습니다.

실제 일어나고있는 일은 시스템이 더 큰 청크로 메모리를 할당한다는 것입니다. 따라서 프로그램에서 정의한 범위를 벗어나지 만 시스템이 작동하는 한 버퍼 오버가 발생하지 않았습니다. 거의 모든 구현이이를 수행합니다. 시스템이 바이트 단위로 수행하는 것보다 16 바이트 청크를 추적하는 것이 더 쉽습니다.

7

1 바이트를 할당 한 다음 할당 된 메모리의 경계를 오버런합니다. sprintf은 범위 검사를하지 않습니다 (친구 인 snprintf는 경계 검사를 수행하지 않습니다).

할당 된 메모리를 오버런하면 정의되지 않은 동작이 발생하므로 아무 일도 발생할 수 없습니다. 귀하의 경우에는 올바르게 작동하는 것 같습니다. 프로그램이 중단되거나 다른 일이 발생할 수 있습니다.

+0

그것이 내가 생각한 것입니다. 그러나 프로그램은 실행 후 "차가운 얼굴"을 인쇄합니다. – facha

+2

다른 최적화 플래그로 컴파일하고 무슨 일이 일어나는 지 지켜보십시오. Betcha 뭔가 다른 일이 발생합니다. –

+2

프로그램이 다른 것을 출력 할 필요는 없습니다. 프로그래머는 올바른 일이 일어나고 있는지 확인해야합니다. (최신 컴퓨터의 경우, 실제로 8 바이트 이상의 청크가 할당되지만, 이것에 의존해서는 안됩니다.) sprintf의 범위를 검사하려면 'snprintf (some1, 1, 멋진 "); 대신. 이름에 'n'을 적어 둡니다. –

2

정의되지 않은 동작!

특히 디버그 빌드에서 malloc()은 보통 합리적인 경계로 할당 요청을 반올림합니다. 그러나 당신은이 행동에 의존해서는 안되며, 오늘날 테스트 프로그램에서 효과가 있다고해서 실제 프로그램에서 작동한다는 것을 의미하지는 않습니다.

2

배열에 "적어도"1 문자를 할당 한 다음 5 문자를 삭제합니다 (문자열의 경우 4 개, \ 0의 경우 1 개). 일반적으로 배열 외부의 메모리를 덮어 쓰는 것이 좋지 않습니다.

효과가있는 이유는 그 밖의 아무 것도 clobbered되지 않는다는 점에서 운이 좋았다는 것입니다.

1

일반적으로 운영 체제가 단순한 부기 또는 다른 이유가 무엇이든 요구하는 것보다 많은 것을 제공합니다. 요청한 양보다 많은 양을 사용하면 프로그램의 동작이 정의되지 않습니다.

Valgrind과 같은 프로그램을 사용하면 잘못된 결과가 있음을 알 수 있습니다.