2012-10-11 48 views
15

Tôi có một số khó khăn trong việc hiểu hành vi của hàm C++ rõ ràng, khi áp dụng cho một vectơ.vector :: rõ ràng trong C++

Tôi cố gắng để biên dịch và chạy các chức năng sau:

#include <iostream> 
#include <vector> 
using namespace std; 

int main() 
{ 
    unsigned int i; 
    vector<int> myvector; 
    myvector.push_back (1); 
    myvector.push_back (2); 
    myvector.push_back (3); 

    cout << "myvector contains:"; 
    for (i=0; i<myvector.size(); i++) cout << " " << myvector[i]; 

    myvector.clear(); 
    myvector.push_back (11); 
    myvector.push_back (12); 

    cout << "\nmyvector contains:"; 
    for (i=0; i<myvector.size(); i++) cout << " " << myvector[i]; 
    cout << endl; 

    cout << " entry3 = " << myvector[2]<<endl; 

    return 0; 
} 

Và đây là kết quả:

myvector contains: 1 2 3 
myvector contains: 11 12 
entry3 = 3 

Làm thế nào là nó có thể là thông tin của mục thứ ba của vector có không bị xóa khi xóa véc tơ?

+2

toán tử [] không xác nhận chỉ số thời gian. Hãy thử thao tác tương tự với .at (n) và xem điều gì xảy ra. – WhozCraig

Trả lời

22

Từ các tài liệu:

Tất cả các yếu tố của vector được giảm: destructors của họ được gọi là, và sau đó chúng được lấy ra từ các thùng chứa vector, để lại container với kích thước 0.

Về cơ bản, bạn đang gọi hành vi không xác định trên myvector[2] vì mục đó không còn tồn tại. Bạn chỉ đẩy 2 phần tử trong vectơ sau khi gọi clear(), do đó chỉ có các chỉ số 01 đều có thể truy cập được.

Bạn không may là nó không bị lỗi, vì việc xuất hiện để làm việc có thể ẩn các lỗi. Không có gì đảm bảo rằng giá trị sẽ bị xóa.

Cố gắng truy cập phần tử với .at(2) thay vào đó sẽ dẫn đến ngoại lệ bị ném (operator[]() không thực hiện bất kỳ kiểm tra ràng buộc nào, trong khi at() sẽ làm).

7

Nếu bạn cố gắng chạy mã này ở chế độ debug, có khả năng nó sẽ gặp sự cố với xác nhận gỡ lỗi. Tham chiếu qua cuối mảng là hành vi không xác định.

Điều thực sự xảy ra là vectơ chưa xóa bộ nhớ trước đây bạn đã sử dụng trước khi chạy clear(). Bộ nhớ này vẫn còn hiện diện nhưng nó không được xác định những gì sẽ xảy ra nếu bạn truy cập nó. Đó là vào bạn để thực hiện giới hạn kiểm tra để tránh chạy ra khỏi cuối của một vector. Bạn có thể làm điều này bằng cách lặp lại với size() dưới dạng giới hạn hoặc bằng cách sử dụng at() và bắt ngoại lệ out_of_range. Tôi sẽ không đặc biệt khuyên bạn nên tiếp cận thứ hai này vì nó không phải là một ý tưởng tốt để sử dụng ngoại lệ cho kiểm tra thời gian chạy.