2011-12-10 3 views
1

최근 C에서 범위 규칙을 읽었습니다. 지역 변수 또는 자동 변수는 선언 된 함수 블록 내에서만 사용할 수 있다고합니다. 함수 밖에서는 더 이상 볼 수 없습니다. 또한 수명은 함수 본문의 마지막 닫기 중괄호 끝까지입니다.범위 규칙 C

이제 여기에 문제가 있습니다. 지역 변수의 주소가 함수에서 호출 함수로 반환되면 어떻게됩니까? 예를 들어

: - 다시 기능 재미에서 제어가 반환 한 번

main() 
{ 
    int *p=fun(); 
} 

int * fun() 
{ 
    int localvar=0; 
    return (&localvar); 
} 

는 변수 지역 변수를 더 이상 살아 없습니다. 그러면 주관사가이 주소의 콘텐츠에 어떻게 액세스 할 수 있습니까?

+0

'main'을 포함한 모든 함수에서 명시 적 리턴 유형을 사용하십시오. 따라서 :'int main (void)'. –

+0

* 머리 스크래치 *. 실용적으로, 당신은 그 주소를 돌려 보내지 않을 것입니다. localvar에 있던 값을 반환 할 것입니다.이 경우, 함수 선언이 잘못되었습니다 ('int'가 아닌'int'를 반환해야하므로). – JayC

+0

[로컬 변수의 메모리를 범위 외부에서 액세스 할 수 있습니까?] (http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope) –

답변

3

주소는 반환 될 수 있지만 주소에 저장된 값은 안정적으로 읽을 수 없습니다. 실제로 대부분의 컴퓨터에서 문제가되지는 않지만 안전하게 할당 할 수 있는지 여부는 명확하지 않습니다.

(읽기 '나쁜을 : 피해야 할를!) 당신은 종종 주소를 읽을 수 있지만 동작은 정의되지 않습니다. 특히 주소는 다른 함수의 다른 변수에 사용될 수 있습니다. 따라서 다른 함수를 호출 한 후이 변수에 액세스하면 포인터를 반환 한 함수가 변수에 저장된 마지막 값을 보지 않을 것입니다.


이유는 다음 함수 적 요구에 대한 포인터를 반환?

하나의 이유는 종종 '동적 메모리'입니다. malloc() 함수 군은 새로운 (스택이 아닌) 메모리에 대한 포인터를 반환합니다.

또 다른 이유는 '나에게 전달 된 값에서이 위치에서 뭔가가 발견되었습니다'입니다. strchr() 또는 strstr()을 고려하십시오.

또 다른 이유는 '함수 또는 함수 소스에 숨겨진 정적 개체에 포인터를 반환하는 것입니다.' asctime() 외 (스레드 안전에 대해 걱정).

아마도 다른 몇 가지가 있지만 가장 일반적인 것일 수 있습니다.

이들 중 어느 것도 로컬 (스택 기반) 변수에 대한 포인터를 반환하지 않습니다.

+0

그게 바로 내가 짐작했던 것입니다. 그렇다면 왜 포인터가 돌아 오는 함수가 필요한지 자세히 설명해 주시겠습니까? 지역 변수의 참조 또는 주소를 함수에서 호출 함수로 반환하려고 할 때마다 위 설명과 동일하기 때문에이 함수의 사용법을 알 수 있습니다. - – qre0ct

0

함수가 반환 된 후 해당 위치를 메모리에서 참조하는 것은 위험합니다. 물론 그 위치는 여전히 존재할 수 있지만 여전히 그 메모리 영역에 대한 클레임이 없으며 프로그램이 계속되고 새 로컬 변수가 스택에 할당 될 때 새 데이터로 덮어 쓰게 될 것입니다.

int * test(int p) { 
    int loc = p; 
    return &loc; 
} 

int main(void) { 
    int *c = test(4); 
    test(5); 
    printf("%d\n", *c); 
    return 0; 
} 

당신이 인쇄 생각 :

t.c: In function ‘test’: 
t.c:3:2: warning: function returns address of local variable [enabled by default] 

이 테스트 프로그램을 고려

gcc

나에게 다음과 같은 경고를 준다?

+0

네, 그건 내가 짐작했던 것입니다. 그렇다면 왜 포인터가 돌아 오는 함수가 필요한지 자세히 설명해 주시겠습니까? 지역 변수의 참조 또는 주소를 함수에서 호출 함수로 반환하려고 할 때마다 위 설명과 동일하기 때문에이 함수의 사용법을 알 수 있습니다. – qre0ct

+0

@ user980153 - 그 대답은 스택 할당과 힙 할당의 차이점을 이해해야합니다. –

0

변수가 없어졌지만 메모리 위치가 여전히 존재하며 사용자가 설정 한 값이 여전히 포함되어있을 수도 있습니다. 그러나 더 많은 함수가 호출되고 메모리 주소가 다른 함수의 로컬 변수에 재사용 될 때 꽤 빨리 덮어 쓸 것입니다. 기능의 지역 변수가 저장되는 곳인 Call Stack에 대해 자세히 알아 보려면 자세히 알아보십시오.

+0

그래, 그게 내가 정확히 짐작했던거야. 그렇다면 왜 포인터가 돌아 오는 함수가 필요한지 자세히 설명해 주시겠습니까? 지역 변수의 참조 또는 주소를 함수에서 호출 함수로 반환하려고 할 때마다 위 설명과 동일하기 때문에이 함수의 사용법을 알 수 있습니다. - – qre0ct

+0

포인터를 반환하는 것은 비효율적이므로 항상 값으로 전달하지 않으려는 대용량 데이터 구조로 작업 할 때 유용합니다. 이러한 큰 구조체는 일반적으로 malloc()을 사용하여 힙에 할당 된 다음 데이터 포인터가 함수 안팎으로 전달됩니다. –