2012-09-13 4 views
0

가능한 중복 :
Can a local variable's memory be accessed outside its scope?로컬 변수의 어드레스 동작을 반환

입력 :

#include <stdlib.h> 
#include <stdio.h> 
int func2(void); 
int* func1(void); 

int func2(void) 
{ 
    int* b; 
    b = func1(); 
    printf("%d", *b); 
    printf("%d", *b); 
    printf("%d", *b); 
} 

int* func1() 
{ 
    int a = 13; 
    return &a; 
} 

int main() 
{ 
    func2(); 
} 

출력 :

13 -1077824828 -1077824828 
,617,

누군가 스택과 OS에서 어떤 일이 일어 났는지 설명 할 수 있습니까? 왜 포인터의 값을 얻은 후에 결과가 13에서 가비지로 바뀌 었습니까?

+4

중복 숫자 무한대에 1을 더한 값입니다. 이것은 정의되지 않은 동작입니다. –

+0

또한,'func2'는 리턴 타입'int'으로 정의되었지만 아무것도 리턴하지 않습니다. –

+0

실제로 질문에 답하기 위해서 : 특별한 경우에,'printf()'의 첫 번째 호출은'func1()'에 대한 호출에서 스택에 남은'13'을 덮어 씁니다. – Mysticial

답변

1

확실히. 결과는 디버그와 릴리스 (클린)에 따라 다릅니다. 어셈블리를 볼 때 로컬 변수는 EBP- (일부 오프셋)입니다. "더 이상"과 같이 스택이 더 높다는 것을 의미합니다.

반환하는 주소입니다.

일반적으로 함수가 반환하는 경우에는 변경되지 않습니다. 일부 컴파일러에서 디버그 빌드에서, 매달려있는 포인터 오류를보다 빨리 잡을 수 있도록 의도적으로 garbaged 것입니다. 이제 printf 호출은 스택의 동일한 주소를 재사용하여 매개 변수를 전달하고 자체 로컬 변수 (일부는 있음)를 전달합니다. 그것들은 func1 return에 의해 비워진 주소에 쓰여지고, 따라서 여러분이 얻은 주소가 가리키는 것을 덮어 씁니다.

+0

왜 printf가 스택에 매개 변수를 전달합니까? 그들은 stdout 버퍼로 직접 보내지 않습니까? – Nizarazo

+0

아니요. 중요하지 않습니다. 호출자 코드를 생성하는 컴파일러는 "printf"의 의미를 알지 못하며, 특히 stdout을 사용하는 것처럼이 함수가 수행 할 작업을 알 필요가 없습니다. –

1

printf를 호출하면 이전에 점유 한 위치를 덮어 쓰는 새 스택 프레임이 생성됩니다. a.

+1

어쩌면 또는 아닐 수도 있습니다. 정의되지 않은 동작을 호출 할 때 어떤 일이 발생하는지에 대해서는 일반적인 의미에서 추론 할 수 없습니다. –

+0

물론 가능합니다. 디마 말이 맞아. 이것은 완벽하게 정의되어 있지만 플랫폼에 따라 다릅니다. –