2012-07-14 4 views
0

아래의 프로그램에서 가상 주소는 두 프로세스 모두 동일합니다. 전역 변수의 이유를 이해했지만 지역 변수를 이해할 수 없었습니다.C와 리눅스의 가상 주소 할당

실행하기 전에 로컬 변수에 가상 주소를 어떻게 할당합니까?

int main() 
{ 
    int a; 
    if (fork() == 0) 
    { 
    a = a + 5; 
    printf(“%d,%d\n”, a, &a); 
    } 
    else 
    { 
    a = a –5; 
    printf(“%d, %d\n”, a, &a); 
    } 
} 
+0

http://en.wikipedia.org/wiki/Call_stack –

+2

덧붙여 말하면, 포인터에는'% d' 대신'% p'를 사용하십시오. –

답변

2

컴파일하는 동안 컴파일러는 스택이나 레지스터를 로컬 변수로 사용하기로 결정합니다. 이 경우 스택.

또한 (가상) 주소 공간에서 스택을 배치 할 위치를 결정합니다.

두 프로세스 모두 스택은 동일한 (가상) 주소에서 시작됩니다. 이 특정 프로그램의 흐름이 결정적이기 때문에 스택 프레임은 두 프로세스 모두에서 동일하게 보이므로 스택에서 'a'에 대해 동일한 오프셋이 발생합니다.

+0

'a'의 수명이 시작되기 전에 * 'fork'는 구현 세부 사항의 결과 일뿐만 아니라 실제로 * 필수 *인데, 그 둘 모두에 같은 주소가 있습니다. 실제로 이것이 어떤 최적화 컴파일러가 어떤 경우에 잘못 될 수 있는지 궁금합니다. 변수가 "fork"이전에 존재해야하므로 스택 변수의 "게으른"할당을 수행합니다 (아마도 VLA가 자식과 부모에서 서로 다른 크기를 할당 한 후에) 부모와 자식 모두에서 동일한 주소를 가져야합니다 ... –

3

가상 주소는 ... 가상입니다. 즉, 두 개의 다른 프로세스 (예 : 상위 프로세스 및 하위 프로세스)의 동일한 가상 주소가 두 개의 서로 다른 실제 주소를 가리 킵니다.

+0

하지만 프로그램을 컴파일 할 때 어떻게 가상 주소가 지역 변수에 주어 집니까? 함수가 올바르게 호출 될 때만 필요합니다. – Dhatri

+0

로컬 변수는 스택에 저장되며 더 이상 필요하지 않으면 제거됩니다. –

+0

로컬 변수는 런타임에 주소를 가져옵니다. 컴파일러는 "주소"가 아니라 스택 포인터에 상대적인 "오프셋"을 제공합니다 (즉, '이 변수는 스택 상단에서 16 바이트 떨어져 있습니다'). 귀하의 경우 스택 포인터는 두 프로세스 모두에서 동일한 오프셋을 적용한 후에도 동일한 주소를 얻게됩니다. –

0

a의 주소가 포크 앞에 있었던 경우 포크 뒤에 반드시 동일해야하므로 a의 주소가 모두 동일하므로 두 프로세스에서 반드시 동일해야합니다. 대부분의 구현에서, a의 주소는 스택 포인터의 내용에 오프셋 (컴파일러에 의해 결정됨)을 추가하여 파생됩니다. 스택 포인터의 내용은 fork에 의해 복제됩니다.