2012-04-30 6 views
5

Tôi đã viết mã nhỏ này chỉ để xem cách một trình vòng lặp thực sự bị vô hiệu và không trỏ đến vị trí thay đổi của một vectơ sau khi đạt được dung lượng của nó.Tại sao không C++ xử lý các trình vòng lặp khi chèn được thực hiện trong một vectơ sau khi đạt được dung lượng?

Ở đây kích thước của vectơ và dung lượng là cả 5 ban đầu. Sau đó tôi chèn một vài phần tử khác vào vectơ và không khởi tạo lại trình lặp của tôi để trỏ đến myvector.begin(). Điều này dẫn đến một giá trị rác của 49 trong đầu ra của tôi sau maximum size of vector is : 1073741823 khi in lại các phần tử của vectơ.

Câu hỏi của tôi là tại sao C++ không làm cho trình lặp điểm trở lại thành myvector.begin() hợp lệ sau khi tất cả các phần tử được sao chép vào vị trí mới?
Điều này cũng có thể dẫn đến một số hành vi có thể khó gỡ lỗi. Tôi biết một cách an toàn để làm việc sẽ là luôn luôn reinitialize iterator chỉ trước khi sử dụng nó.

#include<iostream> 
    #include<vector> 
    #include<stdio.h> 

    using namespace std; 

    int main() 
    { 
    vector<int> myvector; 
    vector<int>::iterator it; 
    int myarray[]= {100,200,300,400}; 
    myvector.insert(it,500); 
    it=myvector.begin(); 
    myvector.insert(it,myarray,myarray+4); 
    it=myvector.begin(); 
    for(;it!=myvector.end();++it) 
    cout <<*it<<endl; 
    cout <<"size of vector is :" << myvector.size() <<"\n"; 
    cout <<"capacity of vector is : " << myvector.capacity()<<"\n"; 
    cout <<"maximum size of vector is : " << myvector.max_size()<<"\n"; 
    myvector.push_back(600); 
    for(;it!=myvector.end();++it) 
    cout <<*it<<endl; 
    } 
    Output of program :- 
    100 
    200 
    300 
    400 
    500 
    size of vector is :5 
    capacity of vector is : 5 
    maximum size of vector is : 1073741823 
    49 
    100 
    200 
    300 
    400 
    500 
    600 
+0

[với 'std :: vector' bất kỳ thứ gì thay đổi kích thước làm mất hiệu lực các trình lặp trước đó] (http://stackoverflow.com/a/6438087/168175) – Flexo

+1

@awoodland, anh ấy biết rằng, tôi nghĩ anh ấy hỏi * lý do * điều này đang xảy ra. –

+1

Mỗi thùng chứa STL đều đảm bảo một số đảm bảo về tính hợp lệ của các trình lặp của nó. Nó trả tiền để hiểu khi vòng lặp không hợp lệ cho một vùng chứa đã cho. Bạn chắc chắn không muốn luôn luôn đặt lại thành một 'bắt đầu()' mới chỉ trong trường hợp '. Xem tại đây để biết thông tin về 'vectơ' - http://www.sgi.com/tech/stl/Vector.html –

Trả lời

9

Vì không thực tế và có thể là không thể.

Sản phẩm vector phải giữ một danh sách của tất cả các lặp và họ sửa đổi tất cả của họ càng sớm càng một phương pháp invalide-kích hoạt được gọi là?

+0

không thể phân bổ không gian được lưu giữ địa chỉ của myvector.begin() và tất cả các trình vòng lặp trỏ đến vị trí đó và sau đó từ đó đến địa chỉ gốc hoặc vị trí bắt đầu của vector.Và địa chỉ này giữ vị trí nhìn chằm chằm của vector được sửa đổi khi không gian mới được phân bổ cho vectơ? Nó sẽ có rất nhiều chi phí? Tôi không phải là chuyên gia để hỏi nó. – Invictus

+1

@Ritesh nó sẽ là rất nhiều chi phí không có lợi ích cụ thể nếu bạn có vô số các vòng lặp. Nó không chỉ là bắt đầu và kết thúc, nhớ bạn, và nó không nhất thiết chỉ là một trong mỗi. –

+1

@Ritesh - bạn luôn có thể tạo một container với các trình vòng lặp thực hiện điều đó, nhưng cho rằng 'std :: list' tồn tại mà không bị vô hiệu khi nó phát triển dường như làm cho nó không đáng giá. – Flexo

3

Có lẽ vì vectơ sẽ phải theo dõi danh sách tất cả các trình lặp của nó và thông báo cho tất cả khi chúng trở nên không hợp lệ. Điều này sẽ giới thiệu khá nhiều chi phí. Các hoạt động của các container STL đều có các quy tắc vô hiệu hóa được chỉ định rất tốt, bạn chỉ cần theo chúng như là lập trình viên.

Lưu ý rằng theo tiêu chuẩn, bạn không thể dựa vào các vòng lặp vector có hiệu lực sau khi chèn hoặc xóa. Rằng nó vẫn làm việc cho bạn cho đến khi thay đổi kích thước là một chi tiết thực hiện.

4

Trình lặp không được gắn với vectơ theo bất kỳ cách nào có ý nghĩa (cách nó có thể được thực hiện như một con trỏ nếu nó là?). Vector không biết về trình lặp. Công việc của bạn là không sử dụng trình lặp không hợp lệ.

Vì vậy, bạn đề xuất thêm một tấn phức tạp vào lớp vectơ cho ... mục đích chính xác là gì? Làm thế nào điều này giải quyết vấn đề trong thế giới thực, nơi chúng ta biết rằng làm một điều như vậy là một ý tưởng tồi?

1

STL không cố gắng triển khai tất cả các vùng chứa có thể. Mặc dù thiết kế vùng chứa của bạn chắc chắn có thể, nhưng nó không được bao gồm. std::vector<T> có vẻ tương tự, nhưng nó cố gắng là một mảng tốt hơn T[] với chi phí thấp. Mục tiêu đó không tương thích trực tiếp với bạn. May mắn thay, thiết kế STL là mô-đun, vì vậy ngay cả khi bạn đã viết vùng chứa của riêng mình để hành động như thế này, bạn vẫn có thể sử dụng lại tất cả thuật toán STL cũng như thuật toán tương thích STL (ví dụ: thuật toán tăng).