2016-09-07 3 views
4

다음 코드를 고려하십시오.C- 함수가 로컬 변수에 대한 포인터를 반환합니다.

#include<stdio.h> 
int *abc(); // this function returns a pointer of type int 

int main() 
{ 
    int *ptr; 
    ptr = abc(); 
    printf("%d", *ptr); 
    return 0; 
} 

int *abc() 
{ 
    int i = 45500, *p; 
    p = &i; 
    return p; 
} 

는 출력 :

45500

내가 link에 따라 알고 행동의이 유형은 정의되지 않습니다. 하지만 왜 내가 프로그램을 실행할 때마다 올바른 가치를 얻고 있는지.

+0

정의되지 않은 동작이 허용됩니다. 그건 그렇고, 나는이 질문에 잘못된 것을 보지 못한다. Upvoted. – Bathsheba

+3

프로그램이 매우 간단하기 때문입니다. 'abc()'와'printf() '호출 사이에 다른 함수 호출을 삽입 해보십시오. – Serge

+3

그래서요? "정의되지 않음"은 "무작위"를 의미하지 않습니다 ... –

답변

3

abc을 호출 할 때마다 스택의 맨 위에있는 영역을 모든 로컬 변수를 쓸 장소로 "표시"합니다. 그것은 스택의 최상위 위치를 나타내는 포인터를 움직여 수행합니다. 이 영역을 스택 프레임이라고합니다. 함수가 돌아 오면 스택 포인터를 원래 위치로 이동하여 해당 영역을 더 이상 사용하지 않으려 함을 나타냅니다. 결과적으로 나중에 다른 함수를 호출하면 스택의 해당 영역을 자신의 용도로 다시 사용하게됩니다. 그러나 귀하의 경우 아직 다른 기능을 호출하지 않았습니다. 스택의 해당 영역이 동일한 상태로 유지됩니다.

위의 내용은 코드의 동작을 설명합니다. 모든 C 컴파일러가 그런 식으로 함수를 구현할 필요는 없으므로 에 의존해서는 안됩니다..

+5

이것은 * 매우 * 구현에 따라 다릅니다. –

+0

예, 저는 그의 호기심을 충족시키기위한 행동 만 설명합니다. – redneb

+0

i8051 용 Keil C 컴파일러 : 링크 시간에 호출 트리를 작성하여 데이터 세그먼트에 로컬을 할당하므로 스택은 컨트롤을 전달하는 데만 사용됩니다. – Serge

2

글쎄, 정의되지 않은 동작은 정의되지 않았습니다. 은 UB (또는 UB을 호출하는 프로그램의 출력)에을 의존 할 수 없습니다.

어쩌면, 은 어쩌면 환경과 당신의 코드, 지역 변수에 할당 된 메모리 위치를 잘 작성하지 여전히 접근를 OS에 의해을 재생 및이지만 하리라는 보장이 없다 다른 플랫폼에 대해서도 동일한 동작입니다.

+0

UB가 무엇입니까 ?? pls는 – Cody

+1

@Cody UB -> 정의되지 않은 동작을 정의합니다. –