2011-09-19 4 views
3

나는 IT가 발생하는 이유를 설명해주십시오 초기화되지 않은 변수에 포인터를 할당하면 값이 변경됩니까?

VisualStudio2010

에서 C++와 함께 연주 해요 :

int a, b; 
int *p, *q; 
cout << a << " " << b; 

인쇄를 "0 0". 자, 이해할 수있는 정수입니다. 초기화되지 않은 정수는 0이어야합니다. 내가 기본에서 초기화되지 않은 변수 그 변화 값으로 포인터를 할당하는 경우 하지만

int a, b; 
int *p, *q; 
p = &a; 
cout << a << " " << b; 

출력은 그래서 "1792816880 0"

입니다. 왜?

편집 설명 : 문제는 의 포인터를 점점 그 가치를 변경할 수있는 방법을 초기화되지 않은 변수

int a; int *p; 
cout << a; // would be 0, because it's loacal variable 
p = &a; 
cout << a; //not 0; 

의 가치에 대해 아니었다? 우리가 변수를 초기화 할 때, 우리는 공간을 할당하고, 어떤 비트를 지정할 수 있지만, "p = &"실제로이 공간에서 비트를 변경합니까?

+0

흥미 롭습니다. Fedora 15 x64_86에서 G ++ 4.6.0에서도 유사한 점이 발생합니다. – trojanfoe

+2

프로젝트 설정에서 경고 수준을 높이십시오. 그것은 초기화되지 않은 변수의 사용법을 감지합니다. – Stephan

+0

아니요. 초기화되지 않은 정수는 0이어야합니다.

답변

6

음이 이해할, 초기화되지 않은 정수는 INT는 지역 변수 인 경우 0

호 그 보장은 없습니다

, 그것은 스토리지 클래스에 따라

는, 그것은을 가지고 있어야한다 자동 저장하고 0

가 초기화되지 변수에 액세스 할 필요가 정의되지 않은 동작의 원인과 당신의 코드는 정의되지 않은 BEH의 원인이되는 avior. 정의되지 않은 동작이 발생하면 모든 베팅이 해제되고 동작을 설명 할 수 없습니다. 정의되지 않은 행동에 대해서는

,

C++ 표준 섹션 1.3.24 상태 :

허용 정의되지 않은 동작이 번역 또는 프로그램 실행 중에 행동에, 예상치 못한 결과가 완전히 상황을 무시 범위 (진단 메시지의 발행 여부에 관계없이) 환경의 특성을 문서화 된 방식으로 해석하거나 진단 메시지를 발행하여 번역 또는 실행을 종료 할 수있다.

편집 :
을 감안할 때 위의이 정의되지 않은 행동이고 하나는 그러한 행동에 의존하는 코드를 작성해서는 안 가리키고 하나는 심지어 코드를 작성하는 생각 안된다고. 관련성이없는 &이 모든 컴파일러의 구현을 파고 들기 때문에 비생산적인 것으로 나타났습니다. 왜 이렇게 작동하는지에 대한 설명을 찾아야합니다.

누군가가이 답장을 찾으면, 당신은 자유롭게 downvote 할 수 있습니다. 만약 downvote count가 upvotes를 초과한다면, 나는 대답이 환영받지 못함을 알게 될 것이고 그것을 삭제할 것이다.

+0

로컬 변수에 대한 참조는 –

+0

입니다. '정의되지 않은 동작'에 대한 답변으로 문제가 해결된다고 생각하지 않습니다. – trojanfoe

+2

@ 트로이안 포 (Trojanfoe) 유일하게 가능한 대답입니다. 프로그램의 동작은 정의되지 않았으므로 거의 모든 일이 발생할 수 있습니다. –

2

초기화되지 않은 값의 값이 정의되지 않았습니다. 기본값은 없습니다. 모든 값이 표시 될 수 있습니다.

겉으로보기에 관계없는 조작으로 소프트웨어가 정의되지 않은 값에 대한 응답으로 사용자에게 알려줄 가비지의 기본 값을 변경할 수 있습니다.

결론은 정의되지 않은 동작이 발생해야하는 것을 추측하지 않습니다. 그것은 단순히 정의되지 않습니다 - 정의되지 않은 동작을 가진 코드를 작성하지 마십시오.

3

이것은 C++에서 "정의되지 않은 동작"입니다.

C++에서 변수를 초기화하지 않으면 항상 0이 아닙니다. 그건 우연히 일어난 일입니다. 메모리가 할당되고 이전에 해당 메모리 위치에 있던 가비지 값이 초기화 될 때까지 출력됩니다.

0

C++은 선언 할 때 변수를 초기화하지 않고 단지 RAM 메모리를 할당합니다. 포인터를 사용하는 경우 metter를 초기화하기 전에 값으로 설정할 수 있습니다. 사용하기 전에 항상 변수를 초기화해야합니다.

+0

RAM? 변수는 스택에 저장됩니다! – trojanfoe

+0

@trojanfoe : 스택이 RAM이 아니라고합니까? – Stephan

+0

당연히 아니지만, 힙과 동일한 방식으로 할당되지 않습니다. – trojanfoe

0

초기화되지 않은 로컬 정수는 C++에서 0이 될 수 있습니다. 그들은 따라서 그들이 0

2

그것은 여기에 정의되지 않은 동작입니다하지만 어떤 일이 될 수 무엇인지에 추측이다 포함한 모든 값이 될 수있다 "쓰레기"이다 : 첫 번째 코드 샘플에서

, 변수의 주소는 절대로 컴파일러가 레지스터에 저장하지 않고 주 메모리에 절대로 존재하지 않고 레지스터의 값이 0이 될 가능성이 있습니다.

두 번째 코드 샘플에서는 변수에 주소를 가질 수 있도록 메모리 (스택에 있음)에 있어야합니다. 기존 데이터에는 임의의 쓰레기가있었습니다.

1

당신은 지금까지 작성되지 않은 많은 변수가 있습니다. 컴파일러는 그러한 변수에 스토리지를 할당하지 않기로 결정할 수 있습니다. 이것은 가혹한 것처럼 보일지 모르지만 현대 컴파일러는 가변 저장을 세분화 된 수준으로 할당하고 일부 변수는 일부 분기에서 사용되지 않을 수 있습니다. 필요하지 않을 때 왜 메모리를 할당해야합니까?

글을 쓰지 않았기 때문에 메모리가 할당되지 않은 "변수"에서 읽으면 어떻게됩니까? 임의의 데이터를 얻을 수 있습니다. 또는 segfault - 정의되지 않은 동작은 여러 형태로 제공됩니다.

두 번째 예를 들어 여기에서 을 수행하고 한 변수에 쓰기, p. a은 쓰기가없는 메모리 할당이 필요하지 않으므로 p이라는 별칭을 사용할 수 있습니다. 그리고 p의 값은 int으로 다시 해석하면 1792816880이 될 수 있습니다.

관련 문제