2013-02-19 2 views
2
#include <stdio.h> 
void func(int **); 

int main() 
{ 

    int *arr[2]; 

    func(arr); 

    printf("value [1] = %d \n",*arr[0]); 

    printf("value [2] = %d \n",*arr[1]); 
    return 0; 
} 

void func(int **arr) 
{ 
    int j = 10; 
    arr[0] = &j; 
    arr[1] = &j; 
} 

코드가 gcc로 컴파일되면 성공적으로 컴파일됩니다. 그러나 출력은 다음과 같습니다.포인터 배열의 가비지 값

value [1] = 10 

value [2] = 32725 

두 번째 값은 가비지 값입니다. 왜 그래야만하지? 배열에 액세스 할 때 이중 포인터를 올바르게 사용할 수 있습니까?

+0

이 함수가 종료 된 후 일부 함수 ('func'의'j')에서 로컬 변수를 사용하는 것은 잘못되었습니다. – osgx

답변

8

Undefined Behavior입니다.
함수 밖의 존재하지 않는 로컬 변수 j의 주소를 저장하고 있습니다.
j은 기능 범위 { }에서만 사용 가능합니다. 이 범위가 끝나면 주소를 통해 j을 참조하면 정의되지 않은 동작이 발생합니다.

정의되지 않은 동작은 관찰 된 특정 동작을 표시하기 위해 컴파일러가 필요하지 않으므로 출력을 표시 할 수 있음을 의미합니다.

+0

및 "자동 저장 클래스"(저장 기간)은 어떻게됩니까? – osgx

+0

@osgx : 그것은 어떻습니까? 이해가 안 돼서 미안해. –

+0

Alok, 일부 pdf 파일에는 단어 "로컬 변수"가 없습니다 ... 예 : 이 파일의 내용은 다음과 같습니다. http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf. 왜 당신이 "지역 변수"라고 불렀던 것의 주소를 취하는 것이 정의되지 않은 행동이라고 생각하는 것입니까? – osgx

0
int j=10; 

은 스택에 할당 된 로컬 변수입니다. 함수 밖에서이를 참조 해제하는 것은 정의되지 않은 동작입니다. 경고 : 당신이 무엇을하고 있는지 확실히 알지 못한다면 어떤 로컬 변수에 대한 포인터도 반환하지 마십시오. 확실하다면 다시 생각해보십시오.

+0

지역 변수의 반환 주소가 합법적 인 경우가 있습니까? – osgx

+1

@osgx 단순히 넣기 : 결코 사용하지 마십시오. –

+0

@phoeagon -이 프로그램을 실행할 때마다 왜 정의되지 않은 동작이 발생하는지 궁금합니다. 첫 번째 value.any 아이디어가 올바르게 인쇄됩니다. – bornfree