2011-12-05 30 views
6

Tôi có một dự án mà tôi cần đọc/ghi các tệp lớn.Hành vi cụ thể của std :: string on studio visual?

Tôi đã quyết định sử dụng ifstream :: read() để đưa các tệp đó vào bộ nhớ trong một lần truyền, thành chuỗi std ::. (mà dường như là cách nhanh nhất để làm điều đó trong C++: http://insanecoding.blogspot.com/2011/11/how-to-read-in-file-in-c.htmlhttp://insanecoding.blogspot.com/2011/11/reading-in-entire-file-at-once-in-c.html)

Khi chuyển đổi giữa các file, sau đó tôi cần phải "thiết lập lại" std :: string sử dụng làm bộ nhớ đệm trước đó (ví dụ, xóa char [] đệm vào bộ nhớ miễn phí)

tôi đã cố gắng:

std::string::clear() 
std::string::assign("") 
std::string::erase(0, std::string::npos) 
std::string::resize(0) 
std::string::reserve(0) 

nhưng, dưới Visual Studio 2008, điều này không giải phóng bộ nhớ sử dụng bên trong std :: string bản thân: đệm cơ bản của nó không được phân bổ. Cách duy nhất tôi tìm thấy để xóa nó là gọi std :: string :: swap (std :: string ("")) để buộc thay đổi bộ đệm bên trong giữa chuỗi std :: thực tế và chuỗi trống trong param.

Tôi thấy hành vi này một chút lạ ...

tôi chỉ thử nghiệm trên Visual Studio 2008, tôi không biết nếu đó là một hành vi STL-tiêu chuẩn hoặc nếu đó là MSVC cụ thể.

Bạn có thể cho tôi một số đầu mối không?

+5

Trao đổi là cách tiêu chuẩn để tạo bộ nhớ dành riêng cho bản phát hành vùng chứa. Và đọc tập tin bằng cách sử dụng 'std :: string' là cách tắt từ cách tối ưu. –

+1

@VladLazarenko: tiêu chuẩn và có thể nhanh nhất. – Nawaz

+3

Tại sao ** sẽ ** bạn mong đợi bất cứ ai để deallocate bộ đệm? C++ 11 thêm 'shrink_to_fit()' rõ ràng để tạo một yêu cầu không ràng buộc cho deallocation. –

Trả lời

4

Khi Vlad và Alf nhận xét, std::string().swap(the_string) là cách C++ 98 để giải phóng khả năng của the_stringthe_string.shrink_to_fit() là cách C++ 11.

Vì lý do tại sao clear(), erase(), resize(), v.v. không làm điều đó, đây là một tối ưu hóa để giảm phân bổ khi bạn sử dụng một chuỗi hơn và hơn. Nếu clear() giải phóng dung lượng của chuỗi, bạn thường phải phân bổ lại một lượng không gian tương tự trên lần lặp tiếp theo, điều này sẽ mất một khoảng thời gian để thực hiện có thể tiết kiệm bằng cách giữ dung lượng xung quanh. Việc triển khai này không được đảm bảo bởi tiêu chuẩn, nhưng nó rất phổ biến trong việc triển khai.

reserve() được ghi chép lại với

dự trữ Gọi() với một đối số res_arg ít hơn công suất() có hiệu lực một yêu cầu co lại không ràng buộc. Cuộc gọi với res_arg < = size() có hiệu lực là yêu cầu thu nhỏ không phù hợp với ràng buộc.

ngụ ý rằng việc triển khai có nhiều khả năng giải phóng dung lượng trên cuộc gọi reserve(). Nếu tôi đọc chúng đúng, libc++ và libstdC++ làm không gian phát hành khi bạn gọi reserve(0), nhưng nó hợp lý cho thư viện của VC++ đã có lựa chọn ngược lại.

Chỉnh sửa: Như penelope nói, hành vi của std::string ở đây có xu hướng chính xác giống như hành vi của std::vector.

+1

Tôi chỉ muốn thêm ... 'string' hoạt động chủ yếu như 'vector' ... và nếu bạn thêm dữ liệu vào 'std :: vector', khi kích thước của nó đạt đến dung lượng dự trữ, nó tăng gấp đôi dung lượng (và không có gì không (phải) xảy ra khi kích thước giảm bớt). Bằng cách này, thời gian chèn ở mặt sau của vec-tơ là hằng số nhiều hay ít trong khi vẫn hiệu quả về trí nhớ: việc đặt trước bộ nhớ (hoạt động chậm) được thực hiện theo cấp số nhân ít thường xuyên theo thời gian, trong khi kích thước của vectơ không bao giờ nhiều hơn gấp đôi kích thước cần thiết – penelope

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