Sự khác biệt giữa std :: resize (n) và std :: shr_to_fit trong C ++?


11

Tôi đã xem qua những tuyên bố này:

resize(n)- Thay đổi kích thước vùng chứa để nó chứa các phần tử 'n'.
shrink_to_fit()- Giảm công suất của container để phù hợp với kích thước của nó và phá hủy tất cả các yếu tố vượt quá khả năng.

Có sự khác biệt đáng kể giữa các chức năng này? họ đến dưới các vectơ trong c ++


thay đổi kích thước sửa đổi kích thước của container, shr_to_fit thì không. Đối với việc sử dụng thông thường, bạn không cần biết về shr_to_fit, nó chỉ khả dụng để cho phép các nhà phát triển tăng hiệu suất mã của họ theo cách thủ công.
NoSenseEtAl

2
Container tiêu chuẩn có kích thướccông suất . Kích thước là số phần tử hiện tại trong vùng chứa, trong khi dung lượng là dung lượng bộ nhớ được phân bổ (khoảng). Thay đổi kích thước thay đổi kích thước, shrink_to_fitthay đổi công suất.
Một số lập trình viên anh chàng

2
Bạn có hiểu sự khác biệt giữa capacitysize?
Khối

Câu trả lời:


12

Các vectơ có hai thuộc tính "độ dài" có nghĩa là những thứ khác nhau:

  • sizelà số phần tử có thể sử dụng trong vector. Đó là số lượng những thứ bạn đã lưu trữ. Đây là một chiều dài khái niệm.
  • capacity là có bao nhiêu phần tử sẽ phù hợp với lượng bộ nhớ mà vectơ hiện đang phân bổ.

capacity >= sizephải luôn luôn đúng, nhưng không có lý do gì để chúng luôn luôn bằng nhau. Ví dụ: khi bạn loại bỏ một phần tử, thu hẹp phân bổ sẽ yêu cầu tạo phân bổ mới một nhóm nhỏ hơn và di chuyển các nội dung còn lại qua ("phân bổ, di chuyển, miễn phí").

Tương tự, nếu capacity == sizevà bạn thêm một phần tử, vectơ có thể tăng phân bổ theo một phần tử (một thao tác "phân bổ, di chuyển, tự do" khác), nhưng thông thường bạn sẽ thêm nhiều hơn một phần tử. Nếu công suất cần tăng, vectơ sẽ tăng công suất của nó nhiều hơn một phần tử để bạn có thể thêm một số phần tử nữa trước khi cần di chuyển lại mọi thứ.

Với kiến ​​thức này, chúng tôi có thể trả lời câu hỏi của bạn:

  • std::vector<T>::resize()thay đổi kích thước của mảng. Nếu bạn thay đổi kích thước nó nhỏ hơn kích thước hiện tại của nó, các đối tượng dư thừa sẽ bị hủy. Nếu bạn thay đổi kích thước lớn hơn kích thước hiện tại của nó, các đối tượng "mới" được thêm vào cuối được khởi tạo mặc định.
  • std::vector<T>::shrink_to_fit()yêu cầu công suất được thay đổi để phù hợp với kích thước hiện tại. (Việc triển khai có thể hoặc không thể thực hiện yêu cầu này. Họ có thể giảm công suất nhưng không làm cho nó bằng với kích thước. Họ có thể không làm gì cả.) Nếu yêu cầu được thực hiện, điều này sẽ loại bỏ một phần hoặc tất cả phần không sử dụng của phân bổ của vectơ. Bạn thường sử dụng điều này khi bạn hoàn thành việc xây dựng một vectơ và sẽ không bao giờ thêm một mục khác vào đó. (Nếu bạn biết trước mình sẽ thêm bao nhiêu mục, sẽ tốt hơn nếu sử dụng std::vector<T>::reserve()để nói với vectơ trước khi thêm bất kỳ mục nào thay vì dựa vào shrink_to_fitlàm bất cứ điều gì.)

Vì vậy, bạn sử dụng resize()để thay đổi bao nhiêu công cụ là khái niệm trong vector.

Bạn sử dụng shrink_to_fit()để giảm thiểu không gian thừa mà vectơ đã phân bổ bên trong mà không thay đổi bao nhiêu công cụ về mặt khái niệm trong vectơ.


2
Lưu ý rằng đó shrink_to_fitkhông phải là tất cả hoặc không có gì. Việc thực hiện có thể làm giảm năng lực một phần. Ví dụ, hãy xem xét một triển khai ràng buộc khả năng của vectơ đối với quyền hạn của hai.
François Andrieux

5

shrink_to_fit() - Giảm công suất của container để phù hợp với kích thước của nó và phá hủy tất cả các yếu tố vượt quá khả năng.

Đó là một sai lầm của những gì xảy ra. Một cách đáng kể, việc phá hủy tất cả các yếu tố ngoài phần năng lực là không chính xác.

Trong C ++, khi bộ nhớ động được sử dụng cho các đối tượng, có hai bước:

  1. Bộ nhớ được phân bổ cho các đối tượng.
  2. Các đối tượng được khởi tạo / xây dựng tại các vị trí bộ nhớ.

Khi các đối tượng trong bộ nhớ được phân bổ động bị xóa, cũng có hai bước, phản ánh các bước xây dựng nhưng theo thứ tự ngược lại:

  1. Các đối tượng tại các vị trí bộ nhớ bị phá hủy (đối với các loại tích hợp, đây là noop).
  2. Bộ nhớ được sử dụng bởi các đối tượng được giải phóng.

Bộ nhớ được phân bổ vượt quá kích thước của container chỉ là bộ đệm. Họ không giữ bất kỳ đối tượng khởi tạo đúng. Đó chỉ là bộ nhớ thô. shrink_to_fit()đảm bảo rằng bộ nhớ bổ sung không có ở đó nhưng không có đối tượng ở những vị trí đó. Do đó, không có gì bị phá hủy, chỉ có bộ nhớ được giải phóng.


2

Theo tiêu chuẩn C ++ liên quan đến shrink_to_fit

Hiệu ứng: shr_to_fit là một yêu cầu không ràng buộc để giảm dung lượng () xuống kích thước ().

và liên quan đến resize

Hiệu ứng: Nếu sz <size (), xóa các phần tử size () - sz cuối cùng khỏi chuỗi. Mặt khác, nối các phần tử được chèn mặc định sz - size () vào chuỗi.

Rõ ràng là các chức năng làm những việc khác nhau. Ngoài ra, hàm thứ nhất không có tham số trong khi hàm thứ hai thậm chí có hai tham số. Chức năng shrink_to_fitkhông thay đổi kích thước của container mặc dù có thể phân bổ lại bộ nhớ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.