2011-12-28 5 views
7

다음은 코드 발췌입니다.GCC 4.5.1에서이 STL 맵의 항목이 초기화되지 않는 이유는 무엇입니까?

std::map<double, double> temp; 

temp[0] = .1; 

cout << temp[1] << endl; 
// result varies based on compiler 

나는 GCC 버전 4.4.1을 사용하여 컴파일 그리고 난 예상대로 나는 temp[1]에서 0의 값을 얻는다. 동료는 GCC 버전 4.5.1에서 컴파일 중입니다. 디버그 모드 (-g 플래그 사용)에서 그는 1000을 얻습니다. 릴리스 모드 (-O2 플래그)를 컴파일 할 때 그는 0을 얻습니다.

내 생각에 이것은지도가 this question 및 그 외 여러 다른 요소를 기반으로 기본 생성자를 호출하기로되어 있다는 점을 제외하면 일반적으로 초기화되지 않은 변수에서 발생하는 문제 유형입니다. 또한

, Josuttis에 의해 C++ 표준 라이브러리는 주장이

더 요소가 아직 새로운 요소는 자동으로지도에 삽입 도착, 존재하지 않은 인덱스와 같은 키를 사용하는 경우. 새 요소의 값은 해당 유형의 기본 생성자에 의해 초기화 된 입니다.

은 왜 디버그 모드에서 GCC 4.5.1에서 초기화되는지도의 요소인가? 다른 사람들이이 행동에 대해 정확히 말한 것을 이해하지 못합니까? 새로운 요소의 기본 구성이 반드시 표준의 일부가 아닌 것입니까? 아니면 컴파일러에서 실제 버그가 될 수 있습니까?

+2

네가 맞아. 어딘가에 메모리 손상이있을 수 있습니다. –

+0

문제를 복제하는 간단한 컴파일 가능한 프로그램을 작성할 수 있습니까? 이렇게하면 일반적으로 문제를 해결할 수 없으면 시스템에서 테스트 할 수 있습니다. –

답변

1

예상대로 코드 발췌는 실제로 진행되고있는 작업을 단순화 한 것입니다. find 명령이 맵에서 사용되었으므로 기본적으로 map[1] 대신 map.find(1)->second이 호출됩니다. 이것은 정의되지 않은 동작을 설명합니다.

4

(인쇄 0) 실제로는 g ++ 4.5.2에서는 -g, -O2 또는 둘 다로 0을 인쇄합니다. 0을 인쇄하지 않으면 거의 확실하게 라이브러리 버그입니다 (또는 동료의 프로그램에 이미 정의되지 않은 동작이 있으므로 모든 베팅이 꺼져 있습니다).

2

예 C++ 표준에 따라 0으로 초기화 될 수 있습니다.

참조 :

C++ 03 표준 :

23.3.1.2지도 요소 액세스[lib.map.access]

T& operator[](const key_type& x);

Returns:(*((insert(make_pair(x, T()))).first)).second.

T() 기본값은 개체를 초기화합니다. 변수의 기본값은

C++ 03 표준 8에 있습니다.형 T의 목적은 의미을 기본 초기화

에 : 5/5
- T가 아닌 POD 클래스 유형 (9 절) 인 경우, T의 기본 생성자가 호출 (및 T가 접근 가능한 디폴트 생성자를 가지고 있지 않다면 초기화는 부적절하다.);
- T가 배열 유형이면 각 요소가 기본값으로 초기화됩니다.
- 그렇지 않으면 개체가 0으로 초기화됩니다.

마지막 사례가 여기 코드에 적용됩니다.

+0

'T()'_value-initializes_ 오브젝트 (§8.5/7). – ildjarn

관련 문제