Chuyển tới nội dung chính

std::string::reserve

#include <string>

void reserve( size_type new_cap = 0 );

Yêu cầu thay đổi dung lượng (capacity) của chuỗi, tức là thay đổi lượng bộ nhớ được cấp phát cho chuỗi, sao cho nó có thể chứa ít nhất một số lượng ký tự được chỉ định mà không cần phải cấp phát lại.

Tham số

new_cap

  • Dung lượng mới được yêu cầu cho chuỗi (tính bằng số lượng ký tự). Tham số này là tùy chọn, nếu không được cung cấp, một giá trị mặc định (implementation-defined) sẽ được sử dụng, thường là tương đương với yêu cầu cấp phát đủ bộ nhớ cho chuỗi.

Giá trị trả về

Không có giá trị trả về

Đặc điểm

  1. reserve() chỉ thay đổi capacity (dung lượng), không thay đổi size (kích thước) hoặc nội dung của chuỗi.
  2. Nếu new_cap nhỏ hơn hoặc bằng capacity() hiện tại, lời gọi reserve() không có tác dụng gì (ngoại trừ trường hợp new_cap bằng 0, nó tương đương với việc gọi reserve() không có tham số, implementation có thể tối ưu riêng).
  3. reserve() có thể làm vô hiệu hóa (invalidate) tất cả các iterator, con trỏ và tham chiếu đến các phần tử của chuỗi nếu nó gây ra việc cấp phát lại bộ nhớ.
  4. Việc cấp phát lại bộ nhớ (khi new_cap lớn hơn capacity() hiện tại) là một thao tác tốn kém, vì vậy nên sử dụng reserve() một cách hợp lý để tối ưu hiệu năng.
  5. reserve() có thể ném ra ngoại lệ std::length_error nếu new_cap vượt quá max_size().
  6. reserve() có thể ném ra ngoại lệ std::bad_alloc nếu không thể cấp phát đủ bộ nhớ.
  7. reserve() không thay đổi số lượng ký tự hiện có trong chuỗi (tức là không thay đổi size() hoặc length()). Nó chỉ ảnh hưởng đến dung lượng (capacity) của chuỗi.
  8. Nếu yêu cầu dung lượng mới lớn hơn dung lượng hiện tại, reserve() có thể dẫn đến việc cấp phát lại bộ nhớ. Điều này có thể làm vô hiệu hóa (invalidate) tất cả các iterator, con trỏ và tham chiếu đến các phần tử của chuỗi.
  9. Nếu yêu cầu dung lượng mới nhỏ hơn dung lượng hiện tại, reserve() không đảm bảo rằng dung lượng sẽ thực sự bị thu hẹp. Việc thu hẹp dung lượng là tùy thuộc vào implementation của thư viện chuẩn. Để yêu cầu thu hẹp dung lượng, hãy sử dụng shrink_to_fit() (từ C++11).
  10. reserve() thường được sử dụng để:
    • Tối ưu hóa hiệu năng: Khi bạn biết trước rằng chuỗi sẽ cần lưu trữ một số lượng lớn ký tự, bạn có thể sử dụng reserve() để cấp phát đủ bộ nhớ ngay từ đầu, tránh việc phải cấp phát lại bộ nhớ nhiều lần khi thêm ký tự vào chuỗi.
    • Tránh làm vô hiệu hóa iterator: Khi bạn cần thực hiện nhiều thao tác chèn (insert) vào chuỗi và muốn giữ cho các iterator, con trỏ, hoặc tham chiếu đến các phần tử của chuỗi không bị vô hiệu hóa do cấp phát lại, bạn có thể sử dụng reserve() để đảm bảo đủ dung lượng trước khi thực hiện các thao tác chèn.

Ví dụ

#include <iostream>
#include <string>

int main() {
std::string str;

std::cout << "Initial capacity: " << str.capacity() << std::endl;

str.reserve(100); // Yêu cầu capacity ít nhất là 100

std::cout << "Capacity after reserve(100): " << str.capacity() << std::endl;
std::cout << "Size after reserve(100): " << str.size() << std::endl;

for (int i = 0; i < 50; ++i) {
str += 'a';
}

std::cout << "Size after adding 50 characters: " << str.size() << std::endl;
std::cout << "Capacity after adding 50 characters: " << str.capacity() << std::endl;

str.reserve(5); // Yêu cầu capacity nhỏ hơn, không có tác dụng
std::cout << "Capacity after reserve(5): " << str.capacity() << std::endl;

str.shrink_to_fit(); // Yêu cầu capacity khớp với size
std::cout << "Capacity after shrink_to_fit(): " << str.capacity() << std::endl;

return 0;
}

Các hàm liên quan

capacityTrả về dung lượng bộ nhớ hiện tại được cấp phát cho chuỗi
shrink_to_fitYêu cầu giảm dung lượng của chuỗi cho khớp với kích thước hiện tại của nó
resizeTrả về số lượng ký tự tối đa mà một đối tượng std::string có thể chứa
max_sizeTrả về số lượng ký tự tối đa mà một đối tượng std::string có thể chứa