2008-11-25 17 views
5

Tôi có một vector với 1000 "nút"Thay đổi bộ nhớ dự trữ của C++ vector

if(count + 1 > m_listItems.capacity()) 
    m_listItems.reserve(count + 100); 

Vấn đề là tôi cũng rõ ràng nó ra khi tôi về làm lại nó.

m_listItems.clear(); 

Dung lượng không thay đổi. Tôi đã sử dụng thay đổi kích thước (1); nhưng điều đó dường như không làm thay đổi công suất. Vậy làm thế nào để thay đổi khoản dự trữ?

+0

Hệ thống của bạn có thiếu bộ nhớ không? Dự trữ như vậy có nghĩa là thêm n mục vào nó sử dụng thời gian O (n^2) và tối đa n + 100 đối tượng có giá trị không gian cộng với lỗi làm tròn. Việc cho phép vectơ mở rộng chính nó sẽ ít mã, thời gian O (n) và trên hầu hết các triển khai sử dụng tối đa 2 * n khoảng trống cộng với làm tròn. –

+0

Hệ thống của tôi rất ngắn trên bộ nhớ (đã nhúng) .. Mã thực sự chỉ là một ví dụ về những gì tôi đang nghĩ đến việc triển khai. Đối với hầu hết các phần tôi nhận được 1000 phần khối từ "bảng" vì vậy nó làm cho tinh thần để thay đổi kích thước trong cùng một tần số. CLEANUP là mối quan tâm chính của tôi. – baash05

Trả lời

20
vector<Item>(m_listItems).swap(m_listItems); 

sẽ giảm m_listItems một lần nữa: http://www.gotw.ca/gotw/054.htm (Herb Sutter)

Nếu bạn muốn xóa nó anyway, trao đổi với một vector rỗng:

vector<Item>().swap(m_listItems); 

trong đó tất nhiên là cách hiệu quả hơn. Không có gì thực sự tốn thời gian đang diễn ra)

+2

Điều đáng nói là trong khi swap() cực kỳ rẻ, việc xây dựng bản sao tạm thời của m_listItems trong trường hợp đầu tiên sẽ yêu cầu sao chép mọi phần tử trong vectơ. Vì vậy, trong khi thanh toán bù trừ các vector hoàn toàn (thiết lập công suất 0) là giá rẻ. Thu hẹp nếu không thì không. – jalf

+1

jalf thực sự. nhưng trình tự đó về bản chất là giống nhau, nếu cần thì sẽ có hàm co(). sự phân bổ lại sẽ là cần thiết anyway:/ –

+1

nhưng điểm của bạn là tốt, vì trong C++ 1x, vectơ có thể di chuyển các phần tử của chúng đến vị trí mới. mã của tôi chỉ cần nhìn vector (std :: move (m_listItems)). swap (m_listItems); sau đó tôi nghĩ rằng –

1

Bạn có thể thử kỹ thuật này từ here

std::vector<int> v; 
// ... fill v with stuff... 
std::vector<int>().swap(v); 
1

Bạn có thể swap nó với một vector mới mà đã mong muốn năng lực.

vector<int> tmp; 
old.swap(tmp); 
1

Theo như tôi có thể nói, bạn không thể phân bổ lại một véc-tơ thành dung lượng thấp hơn bao giờ hết; bạn chỉ có thể phân bổ nó lớn hơn. Có nhiều lý do tốt cho việc này; trong số đó là quá trình tái phân bổ là cực kỳ tốn kém tính toán. Nếu bạn thực sự cần phải có một véc tơ nhỏ hơn, hãy giải phóng cái cũ và tạo một cái mới nhỏ hơn. Đó là thực sự tính toán đơn giản hơn nhiều so với việc có vector thực sự thay đổi kích thước nhỏ hơn.

+0

làm thế nào để bạn giải phóng nó? – baash05

+0

Tùy thuộc vào cách nó được phân bổ - bạn hoặc để cho nó đi ra khỏi phạm vi, hoặc bạn gọi xóa. Tôi không nghĩ rằng đây là lời khuyên tốt so với trao đổi. –

2

Bạn có thể trao đổi các vector như những người khác đã gợi ý, và như mô tả trong http://www.gotw.ca/gotw/054.htm nhưng lưu ý rằng nó là không miễn phí, bạn đang thực hiện một bản sao của tất cả các yếu tố, bởi vì các vector phải phân bổ một mới, nhỏ hơn , đoạn bộ nhớ và sao chép tất cả nội dung cũ. (Hoạt động hoán đổi về cơ bản là miễn phí, nhưng bạn đang hoán đổi với một bản sao của dữ liệu ban đầu được tạo ra với một bản sao của dữ liệu vectơ ban đầu, là không phải là miễn phí)

Nếu bạn biết trước lớn như thế nào, bạn nên phân bổ kích thước phù hợp để bắt đầu, do đó, không cần thay đổi kích thước:

std::vector<foo> v(1000); // Create a vector with capacity for 1000 elements 

Và nếu bạn không biết trước, tại sao nó lại lãng phí một chút không gian? Có đáng để thời gian sao chép mọi phần tử vào một vectơ mới và nhỏ hơn (đó là những gì std :: vectơ (v) .swap (v) sẽ làm), chỉ để tiết kiệm vài kilobyte bộ nhớ?

Tương tự, khi bạn xóa véc tơ, nếu bạn định nạp lại nó thì, đặt công suất về 0 có vẻ là một sự lãng phí thời gian ấn tượng.

Sửa:

baash05: những gì nếu bạn đã có 1000000 mục một 10 meg ram.bạn có nói số giảm số tiền trên không là quan trọng không?

Không đổi kích thước vector yêu cầu Bộ nhớ tạm thời, vì vậy nếu bạn bị hạn chế về bộ nhớ, điều đó có thể làm hỏng ứng dụng của bạn. (Bạn phải có vector ban đầu trong bộ nhớ, tạm thời, trước khi bạn có thể trao đổi chúng, do đó bạn sẽ sử dụng tối đa gấp đôi RAM tại thời điểm đó). Sau đó, bạn có thể tiết kiệm một lượng bộ nhớ nhỏ (tối đa một vài MB), nhưng điều này không quan trọng, bởi vì dung lượng dư thừa trong véc-tơ sẽ không bao giờ được truy cập, vì vậy nó sẽ được đẩy tới tệp trang, và do đó không được tính vào giới hạn RAM của bạn ngay từ đầu.

Nếu bạn có 1000000 mục, thì bạn nên khởi tạo vectơ theo đúng kích thước ở vị trí đầu tiên.

Và nếu bạn không thể làm điều đó, thì bạn sẽ thường tốt hơn là không để lại dung lượng một mình. Đặc biệt là kể từ khi bạn nói rằng bạn sẽ nạp lại véc tơ, bạn chắc chắn nên sử dụng lại dung lượng đã được cấp phát, thay vì phân bổ, phân bổ lại, sao chép và giải phóng mọi thứ liên tục.

Bạn có hai trường hợp có thể xảy ra. Bạn biết bạn cần lưu trữ bao nhiêu phần tử hoặc bạn không cần. Nếu bạn biết, sau đó bạn có thể tạo ra vectơ với kích thước chính xác ngay từ đầu, và vì vậy bạn không bao giờ cần phải thay đổi kích cỡ nó, hoặc bạn không biết, và sau đó bạn cũng có thể giữ dung lượng dư thừa, vì vậy ít nhất nó sẽ không phải thay đổi kích thước trở lên khi bạn nạp lại véc-tơ của mình.

+0

nếu bạn có 1000000 vật phẩm với 10 megabyte ram. bạn sẽ nói giảm số lượng trên không là quan trọng? – baash05

+0

Không, không thường xuyên. Xem chỉnh sửa của tôi. – jalf