2011-12-28 22 views
7

Đây là đoạn trích đoạn mã.Tại sao các mục nhập của bản đồ STL này không được khởi tạo trong GCC 4.5.1?

std::map<double, double> temp; 

temp[0] = .1; 

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

Tôi đang biên soạn bằng phiên bản GCC 4.4.1 và tôi nhận giá trị 0 từ temp[1], như tôi mong đợi. Đồng nghiệp của tôi đang biên dịch trên phiên bản GCC 4.5.1. Trong chế độ gỡ lỗi (với cờ -g), anh ta nhận được 1000. Khi biên dịch chế độ phát hành (-O2 cờ), anh ta nhận được 0. Tôi nghĩ rằng đây là loại vấn đề thường phát sinh với các biến chưa được khởi tạo, ngoại trừ bản đồ được cho là sẽ gọi hàm tạo mặc định trên các phần tử của chúng, dựa trên this question và một số khác thích nó.

Hơn nữa, C++ thư viện chuẩn bởi Josuttis, khẳng định rằng

Nếu bạn sử dụng một chìa khóa như chỉ số, mà không có yếu tố chưa tồn tại, một nguyên tố mới được đưa vào bản đồ tự động. Giá trị của phần tử mới là được khởi tạo bởi hàm tạo mặc định thuộc loại của nó.

Tại sao các yếu tố trong bản đồ không được khởi tạo trong GCC 4.5.1 ở chế độ gỡ lỗi? Tôi không hiểu những gì người khác đã nói về hành vi này một cách chính xác? Việc xây dựng mặc định các yếu tố mới một cái gì đó không nhất thiết phải là một phần của tiêu chuẩn? Hoặc điều này có thể là một lỗi thực tế trong trình biên dịch?

+2

Bạn nói đúng. Bạn có thể có tham nhũng bộ nhớ ở một nơi khác. –

+0

Bạn có thể viết một chương trình đơn giản để sao chép lại được vấn đề không. Làm như vậy thường sẽ giải quyết được vấn đề của bạn nếu không thì chúng tôi có thể kiểm tra nó trên hệ thống của chúng tôi. –

Trả lời

1

Như người ta mong đợi, đoạn trích mã là một phiên bản đơn giản của những gì thực sự đang diễn ra. Nó chỉ ra rằng một lệnh tìm được sử dụng trên bản đồ, do đó, về cơ bản map.find(1)->second đang được gọi, thay vì chỉ đơn giản là map[1]. Điều này giải thích hành vi không xác định.

4

Nó sẽ hoạt động theo cách bạn nói (in 0), và trên thực tế trong g ++ 4.5.2 nó in 0 với -g, -O2 hoặc cả hai. Nếu nó không in 0 thì đó chắc chắn là một lỗi thư viện (hoặc chương trình đồng nghiệp của bạn đã có hành vi không xác định trong trường hợp tất cả các phiên cược bị tắt (TM)).

2

Có đảm bảo được khởi tạo thành 0 theo tiêu chuẩn C++.

tham khảo:

C++ 03 Tiêu chuẩn:

23.3.1.2 bản đồ truy cập yếu tố[lib.map.access]

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

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

T() mặc định khởi tạo một đối tượng. Mặc dù giá trị mặc định cho các biến được bao gồm trong:

C++ 03 Chuẩn 8.5/5:

Để mặc định-khởi một đối tượng kiểu T có nghĩa là:
- nếu T là một-POD phi kiểu lớp (khoản 9), các nhà xây dựng mặc định cho T được gọi là (và việc khởi tạo bị lỗi nếu T không có hàm tạo mặc định có thể truy cập được);
- nếu T là một loại mảng, mỗi phần tử được khởi tạo mặc định;
- nếu không, đối tượng không được khởi tạo.

Trường hợp cuối cùng áp dụng cho mã của bạn tại đây.

+0

'T()' _value-initializes_ một đối tượng (§8.5/7). – ildjarn

Các vấn đề liên quan