2009-10-20 92 views
5

最近我已經注意到下面的語句不是真的給出std::string s爲什麼不是std :: string :: max_size()== std :: string :: allocator :: max_size()

s.max_size() == s.get_allocator().max_size(); 

我發現這個有趣的,默認情況下std::string將使用std::allocator<char>其中有size_type(-1)一個理論極限(是的,我知道我假設2的補,但這是無關的實際問題)。我知道實際的限制會比這少很多。在一個典型的32位x86系統上,內核將佔用2GB(可能是1GB)的地址空間,實際上限要小得多。

無論如何,GNU libstdC++的std::basic_string<>::max_size()似乎返回相同的值,無論它使用的分配器說什麼(類似於1073741820)。

那麼問題依然存在,爲什麼std::basic_string<>::max_size()只是返回get_allocator().max_size()?在我看來,這是假設的上限。如果分配不足,它只會拋出一個std::bad_alloc,所以爲什麼不嘗試?

這比其他任何事情都好奇,我只是想知道爲什麼兩個至少在這一個實現分開定義。

+0

「如果。分配不足,它只會拋出一個std :: bad_alloc,所以爲什麼不嘗試?「我可以爲你解答。人們可能需要處理大型字符串,並將其拆分爲大字符串塊,如果他們實際上不能依賴於max_size向他們報告什麼,他們將不得不求助於臨時限制。 – GManNickG

+0

我明白你的觀點,但我不同意。實際情況是,你總是必須假定任何字符串大小<='max_size()'都有可能失敗,因爲它依賴於一個外部變量(堆中有多少可用)。 –

+0

同意。我唯一的一點是,他們至少應該努力做到準確,不要只是給出一個大數字,並希望最好。給實際的數字帶來最好的希望。 :)但棘手的問題。 – GManNickG

回答

10

Microsoft Connect發佈了與您的問題相關的錯誤。微軟有一個有趣的答案:

根據我們對標準的解釋,我們已經解決它作爲By Design,它沒有清楚地解釋max_size()的預期目的是什麼。 Allocator max_size()被描述爲「可以有效地傳遞給X :: allocate()」的最大值(C++ 03 20.1.5 [lib.allocator.requirements]/Table 32),但容器max_size()是描述爲「最大可能容器的尺寸()」(23.1 [lib.container.requirements] /表65)。 Nothing沒有描述是否應該從allocator max_size()派生容器max_size()。我們多年來的實現已經直接從allocator max_size()派生出容器max_size(),然後將這個值用於溢出檢查等等。標準的其他解釋,比如你的,也是可能的,但對我們來說並不是毫不含糊。標準的措辭當然可以從這裏得到澄清。除非和直到發生這種情況,否則我們決定保留當前的實施不變,原因有兩個:(1)其他客戶可能依賴於我們目前的行爲;(2)max_size()基本上不會購買任何東西。至多,使用分配器(比如容器)的東西可以使用分配器max_size()來預測allocate()何時失敗 - 但是簡單地調用allocate()是一個更好的測試,因爲分配器會決定釋放內存。使用容器的東西可以使用容器max_size()作爲size()大小的保證,但更簡單的保證是size_type的範圍。

此外here你可以找到核心問題#197。委員會已經考慮要求改進標準的措辭,但是它被拒絕了。

因此,你的問題的答案「爲什麼..?「是標準沒有清楚地解釋max_size()的預期目的是什麼

4

我不是很確定,但據我所知std::basic_string在當前標準中並不限制將字符串存儲在連續內存中。例如,它可能將其存儲在多個塊中。每個這樣的塊然後限於std::allocator::max_size(),但總和可能大於該值。

此外,它似乎與STL容器的情況。畢竟std::basic_string是一個容器。

+0

除了沒有人可能以這種方式實現它,下一個標準可能不允許它(不完全確定),並且OP看到它比分配器允許的更小*。 – UncleBens

1

GCC的實現有一條評論他們如何計算max_size(必須減去內部管家對象的大小,該內部管理對象被分配爲單個塊與字符串),然後補充說,max_size()返回四分之一,沒有給出的基本原理,所以也許它只是一個安全邊界?(它也應該提供一個繩類,這可能會用於這麼大的字符串? )

用VC++ max_size()回報少一個比allocator.max_size() - 大概佔終止空字符

相關問題