2012-01-19 36 views
6

Tôi không chắc chắn những gì sai với mã này:Tại sao cuộc gọi đến std :: vector :: back() sụp đổ chương trình của tôi

std::vector<int> myVector(0); 

if (myVector.back() == 12) 
    myVector.push_back(12); 

Dường như gọi trở lại() trên một vector rỗng treo các chương trình.

Tôi không hiểu tại sao nó bị lỗi? Chúng ta có cần kiểm tra độ dài của vector trước khi gọi back() không? hoặc có thể đó là một lỗi?

Tài liệu nói rằng nếu vectơ trống thì nó sẽ trả lại giá trị không xác định.

+1

Tôi nghi ngờ số tiền cho người nào đó cấp cho bạn -1 để sử dụng MSDN làm tham chiếu thay vì tiêu chuẩn C++. Các nhà triển khai được phép xác định thêm những gì họ thực hiện trong trường hợp tiêu chuẩn nói là UB, vì vậy nếu MS muốn đảm bảo rằng 'back()' sẽ trả về khi được sử dụng trên một vectơ trống, chúng có quyền làm như vậy. Nếu bạn đang sử dụng MSVC++ thì bạn có quyền đọc tài liệu của họ. Nhưng thay vào đó, nó có thể là -1 vì không nhận ra rằng sử dụng "giá trị không xác định" theo bất kỳ cách nào, có thể gây ra sự cố. –

+0

@SteveJessop Tôi sẽ nghĩ rằng MSDN là việc thực hiện tiêu chuẩn C++. Nhưng nó cảm thấy kỳ lạ mà gọi một phương pháp trên một yếu tố hợp lệ (theo như tôi biết một trống là vector là một yếu tố hợp lệ) tai nạn chương trình của tôi. Vâng, nếu tiêu chuẩn nói như vậy, do đó, được nó :) – MBen

+1

MSVC++ là * một * thực hiện (xấp xỉ) tiêu chuẩn C++. Các triển khai khác hoạt động khác nhau, nếu tiêu chuẩn không nói rõ hành vi. Lý do tiêu chuẩn không xác định việc gọi 'back()' trên một vectơ trống là việc triển khai như vậy không cần mã đặc biệt cho nó. Do đó, họ có thể chọn để nhanh hơn họ sẽ phải kiểm tra xem liệu vectơ có trống hay không, và làm những việc khác nhau trong các trường hợp khác nhau. Họ sẽ dễ bị tai nạn (hoặc tệ hơn) khi bạn làm điều gì sai trái. Nó có thể cảm thấy kỳ lạ, nhưng đó là một sự đánh đổi được thực hiện như là một phần của thiết kế của ngôn ngữ. –

Trả lời

13

chúng ta có cần kiểm tra độ dài của vectơ trước khi gọi lại() không?

Trong một từ: có. Đây là lỗi của bạn, vector của bạn trống nên không có phần tử "back".

Tài liệu nên nói (nếu có bất kỳ điều gì), gọi back() trên một véc tơ trống gây ra hành vi chưa xác định, không phải trả về giá trị không xác định. C++ 11 tiêu chuẩn

+0

Đối với một số lý do, MSDN không nói "giá trị trả về là không xác định" (http://msdn.microsoft.com/en-us/library/0532x4xk%28v=vs.80%29.aspx). Nhưng nó cũng nói, "Khi biên dịch với _SECURE_SCL 1, một lỗi thời gian chạy sẽ xảy ra nếu bạn cố truy cập một phần tử trong một vectơ trống". Tôi không biết (a) tại sao MS đề cập đến một tham chiếu là "giá trị", hoặc (b) cách chúng vuông góc khái niệm "giá trị không xác định" với khái niệm tham chiếu dẫn đến lỗi thời gian chạy khi được sử dụng . Nhưng lỗi thời gian chạy đó cũng có thể là cùng một điều mà người hỏi mô tả là "bị rơi". –

+0

Tôi vẫn nghĩ rằng việc gọi phương thức trên một phần tử hợp lệ sẽ làm hỏng chương trình của tôi. – MBen

+0

@MBen: Nhưng không có yếu tố nào trong vectơ của bạn; đó là điều kiện tiên quyết của 'back()' rằng có ít nhất một phần tử trong vector của bạn. Đó là cách giao diện được xác định. Bạn cần đảm bảo rằng đầu vào của bạn tuân thủ điều kiện tiên quyết trước khi cố gắng gọi 'back()'. –

5

nói này:

23.3.2.8/3

Các e ff vv gọi trước() hoặc quay trở lại() cho một mảng không có kích thước là fi unde Ned.

Do hành vi không xác định, mọi thứ đều có thể xảy ra. Bạn đã may mắn để có được một vụ tai nạn.

+0

Tôi không nghĩ rằng tôi may mắn, nó cảm thấy kỳ lạ mà gọi một phương pháp trên một hợp lệ giá trị làm hỏng chương trình của tôi. – MBen

+3

@MBen Có một sự cố chương trình trên UB là tốt, bởi vì nó dễ dàng để bắt lỗi. Khi nó đôi khi hoạt động và đôi khi không, rất khó để tìm lỗi. –

+0

Tôi đồng ý. Tôi chỉ cần chắc chắn rằng vector có các phần tử :-) – MBen

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