2011-10-15 41 views
5

Câu hỏi nhanh. Giả sử tôi khai báo một vector có kích thước 20. Và sau đó tôi muốn thêm một vài số nguyên vào nó bằng cách sử dụng push_back.Trong C++, hàm vectơ push_back có tăng kích thước của một mảng trống không?

vector<int> myVector(20); 
myVector.push_back(5); 
myVector.push_back(14); 

Dung lượng của véc tơ của tôi bây giờ là 22 hoặc vẫn là 20? Lần lượt là 5 và 14 đã được thêm vào chỉ mục [19] và [20]? Hay họ ở [0] và [1]?

+13

Đừng ngần ngại để thực sự cố gắng này * mình *. –

+0

Chào mừng bạn đến với StackOverflow, tôi hy vọng bạn đọc [FAQ] (http://stackoverflow.com/faq#howtoask). –

Trả lời

11

Sau những tuyên bố đó, dung lượng của nó được xác định thực hiện. (Xin lưu ý rằng khác với kích thước của nó.)


vector<int> myVector(20); 

Điều này tạo ra một vector đầy hai mươi 0 của. Kích thước của nó là hai mươi, chính xác, và năng lực của nó là ít nhất hai mươi. Có hay không chính xác hai mươi được xác định thực hiện; nó có thể có nhiều hơn (có thể là không, trong thực tế).

myVector.push_back(5); 

Sau đó, phần tử thứ hai của mảng là 5 và công suất được xác định lại một lần nữa. (Nếu công suất đã được chính xác hai mươi trước, nó hiện đang tăng một cách không xác định.)

myVector.push_back(14); 

Tương tự như vậy, bây giờ là yếu tố thứ hai mươi hai của mảng là 14, và khả năng là thực hiện xác định.


Nếu bạn muốn dành không gian, nhưng không chèn các yếu tố, bạn muốn làm điều đó như thế này:

vector<int> myVector; 
myVector.reserve(20); // capacity is at least twenty, guaranteed not 
         // to reallocate until after twenty elements are pushed 

myVector.push_back(5); // at index zero, capacity at least twenty. 
myVector.push_back(14); // at index one, capacity at least twenty. 
+1

Lưu ý rằng chuẩn C++ 03 23.2.4/1 yêu cầu thời gian không đổi 'vector' hỗ trợ ** (khấu hao) ** chèn và xóa các hoạt động ở cuối ", do đó, trong thực tế, công suất thường mở rộng bởi một hệ số hai khi 'push_back()' cần nhiều chỗ hơn. –

+0

Được rồi. Cảm ơn bạn. Tôi không biết nó sẽ lấp đầy với 20 0. Điều đó sẽ thực sự làm hỏng chương trình của tôi. Tôi không biết tại sao tôi không nghĩ đến việc không chỉ định kích thước, xem chúng hoạt động như thế nào và đó là những gì tôi cần. Một derp thay mặt tôi. – iaacp

1

push_back làm tăng kích thước của std::vector và đặt các yếu tố mới ở mặt sau của vector (container khác cũng có một phương pháp push_front để làm điều tương tự ở phía trước cũng).

Tuy nhiên, có sự khác biệt giữa kích thước và dung lượng của vector. Kích thước đề cập đến số lượng mục thực tế trong số vector ngay bây giờ; khả năng đề cập đến tổng số mục mà vector có thể giữ mà không cần tái phân bổ bộ nhớ. Có thể để reserve() bộ nhớ nếu bạn biết rằng bạn sẽ thêm một số thành phần và không muốn phát triển phần vector.

+0

Được rồi, vì vậy push_back không tăng dung lượng, phải không? Trừ khi vector đó đã hết công suất. – iaacp

+0

Đúng, nó không nhất thiết phải tăng dung lượng. Tôi chỉ đề cập đến nó bởi vì 'std :: vector' gặp rắc rối khi phân biệt nên điều quan trọng là giữ các điều khoản thẳng, đặc biệt khi đọc tài liệu cho' std :: vector'. –

1

Như vector là không có sản phẩm nào nhưng có kích thước 20 (chứa 20 nguyên tố) và bạn push 2 yếu tố để các back, nó bây giờ chứa 22 nguyên tố. Nhưng các phần tử mới không được đặt tại các chỉ số 19 và 20, nhưng 20 và 21.

Nếu bạn thực sự muốn đặt trước đủ bộ nhớ để giữ 20 phần tử (mà không chứa bất kỳ phần tử nào) để ngăn chặn phân bổ tốn kém , sau đó bạn nên gọi

std::vector<int> myVector; 
myVector.reserve(20); 

Trong trường hợp này các vector vẫn còn trống rỗng, nhưng nó có đủ bộ nhớ để thêm ít nhất 20 phần tử (sử dụng push_back, ví dụ) mà không cần phải tái phân bổ lưu trữ nội bộ của mình. Trong trường hợp này, vectơ chỉ chứa 2 phần tử bạn push ed _back.

+0

Rất hữu ích, cảm ơn bạn. Về cơ bản những gì tôi muốn làm là tạo ra một vector, và chỉ thêm các phần tử vào cuối. Nó không xảy ra với tôi rằng tôi thậm chí không phải cung cấp cho một kích thước ban đầu, bởi vì vectơ là năng động. Cảm ơn bạn! – iaacp

3
  • size là số phần tử trong vùng chứa vector.
  • capacity là kích thước của không gian lưu trữ phân bổ
  • push_back hiệu quả làm tăng kích thước vector bởi một, khiến việc phân bổ lại việc lưu trữ phân bổ nội nếu kích thước vector là tương đương với công suất vector trước khi cuộc gọi.

Thông tin thêm: http://www.cplusplus.com/reference/stl/vector/

+0

Hoàn hảo. Cảm ơn bạn! – iaacp

1

Vâng, vector có hàm thành viên push_back. Các trình tự khác như dequepush_front.

0, 1, 2, ......, thức

sau khi bổ sung:

0, 1, 2, ....., cuối cùng, Ngoài ra, ...

Bạn có thể nhớ lại rằng:

capacity() returns the number of elements in the vector sufficient, 
without allocating additional memory. 
This number can be greater or equal to size. 

Đó là, bạn không thể thêm vào phía trước hoặc giữa, kể từ khi vector chuyên để truy cập nhanh đến các yếu tố của chỉ số. Nếu bạn muốn thêm ở phía trước và phía sau, bạn có thể sử dụng deque tương tự như vector. Nếu bạn muốn thêm vào trước, sau và bất cứ nơi nào bạn có thể sử dụng list. Lưu ý rằng list không cung cấp chỉ mục như dequevector.

Tuy nhiên, một vectơ được giả định có nhiều dung lượng hơn kích thước thực tế của nó. Khi bạn thêm các phần tử vào nó, nó không cần thiết cấp phát bộ nhớ bổ sung. Nó chỉ khi dung lượng bằng kích thước. Trên nhiều trình biên dịch, dung lượng mới sẽ gấp đôi dung lượng cũ. Sau khi phân bổ, nó sao chép tất cả các phần tử ở vị trí mới. Tuy nhiên, hành vi này có thể tốn kém về mặt bộ nhớ.

1

push_back sẽ tăng dung lượng của vec-tơ lên ​​ít nhất là kích thước mới của vectơ, nhưng có thể (nghĩa là) có phần lớn hơn.

Vì yêu cầu push_back để chạy trong O (1) thời gian khấu hao, mỗi lần phân bổ lại sẽ là một số bội số của dung lượng cũ. Trong triển khai điển hình, số nhiều là 2.

Tuy nhiên, việc tăng dung lượng chính xác không được chỉ định. Nếu bạn yêu cầu kiểm soát chính xác dung lượng, hãy sử dụng reserve.

...

Đọc lại câu hỏi của bạn, tôi không chắc chắn rằng bạn hiểu sự khác biệt giữa kích thước của vector và năng lực của mình. Kích thước là số phần tử. Dung lượng là số phần tử mà vectơ có thể giữ mà không thực hiện phân bổ lại. Tức là, bạn có thể push_back công suất() - size() các yếu tố trước khi phân bổ lại xảy ra.

Trong ví dụ của bạn, 5 và 14 sẽ xuất hiện tại myVector [20] và myVector [21], tương ứng.

+0

Phải. Điều tôi không hiểu là các vectơ không đòi hỏi khả năng khi tạo ra chúng, đó là chúng là điểm - chúng năng động, đúng không? Vì vậy, nó là loại vô nghĩa để cung cấp cho họ một năng lực ban đầu. – iaacp

+0

@iaacp: Không, nó không phải là vô nghĩa. Nếu bạn biết trước bao nhiêu thứ bạn dự định đặt bên trong vectơ, nhưng bạn không có sẵn những thứ thực tế khi khởi tạo vectơ, thì bạn có thể 'dự trữ()' một số để cho 'vectơ' sẽ không phải làm bất kỳ sự phân bổ lại nào. –

+0

@iiacp: Nó không phải là vô nghĩa nếu bạn thực sự quan tâm đến tái phân bổ. Việc phân bổ lại (a) cần thời gian và (b) vô hiệu hóa các tham chiếu/con trỏ tới các phần tử bên trong vectơ. 'dự trữ' cho phép bạn đặt khả năng tránh việc phân bổ lại trong tương lai. Lưu ý rằng ví dụ của bạn đặt _size_ của vectơ, chứ không phải _capacity_. Bạn đang tạo một vectơ gồm 20 số nguyên chưa được khởi tạo. – Nemo

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