2011-12-05 35 views
6

我有一個需要讀/寫大文件的項目。在visual studio上的std :: string的具體行爲?

我決定使用ifstream :: read()將這些文件放入內存中,一次傳遞到std :: string中。 (這似乎是做在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

當文件之間切換,然後我需要「重啓」用作先前內存緩衝區的std :: string(即刪除的char []緩衝區以釋放內存)

我想:

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

但是,Visual Studio 2008的下,這不會釋放的std :: string本身內部使用的內存:它的基礎緩衝區沒有被分配。

我發現刪除它的唯一方法是調用std :: string :: swap(std :: string(「」)) 強制更改實際std :: string和空的std :: string之間的內部緩衝區在參數。

我覺得這種行爲有點怪......

我只在Visual Studio 2008中測試過,我不知道這是否是一個STL標準的行爲,或者如果它是MSVC特有的。

你能給我一些線索嗎?

+5

交換是一種使容器釋放保留內存的標準方式。使用'std :: string'讀取文件的方式與最佳方式不同。 – 2011-12-05 14:22:08

+1

@ VladLazarenko:標準,可能最快。 – Nawaz

+3

爲什麼**你會希望任何人釋放緩衝區? C++ 11增加了明確的'shrink_to_fit()'來做一個非約束請求來解除分配。 –

回答

4

正如Vlad和Alf所評論的,std::string().swap(the_string)是C++ 98發佈the_string容量的方式,而the_string.shrink_to_fit()是C++ 11的一種方式。

至於爲什麼clear(),erase(),resize()等不這樣做,這是一個優化,當您反覆使用字符串時減少分配。如果clear()釋放了字符串的容量,那麼通常必須在下一次迭代中重新分配相似數量的空間,這需要一段時間才能通過保持周圍的容量實現節省。標準並不保證這種實現,但在實現中很常見。

reserve()是記錄與

調用儲備()與res_arg參數小於容量()實際上是一個非約束性的收縮的要求。與res_arg < = size()的調用實際上是一個非約束性的適應請求。

這意味着實施更有可能在reserve()呼叫上釋放容量。如果我正確地讀取它們,當你調用reserve(0)時,libc++和libstdC++會釋放空間,但VC++的庫做出了相反的選擇是合理的。

編輯:正如penelope所說,std::string在這裏的行爲往往和std::vector的行爲完全一樣。

+1

我只想補充一點......'string's的行爲大體上與'vector's ​​...相似,如果你將數據添加到'std :: vector',當它的大小達到保留容量時,它就是容量翻倍(當尺寸減小時,沒有東西不必(必須))。這樣,矢量後面的插入時間或多或少是恆定的,而仍然是高效的存儲器方式:隨着時間的推移,存儲器保留(緩慢操作)以指數方式更少地頻繁地完成,而矢量的大小從不比所需尺寸大兩倍以上 – penelope

相關問題