簡體   English   中英

為什么 C++ 分配器中沒有重新分配功能?

[英]Why is there no reallocation functionality in C++ allocators?

在 C 中,標准的內存處理函數是malloc()realloc()free() 然而,C++ stdlib 分配器只並行其中兩個:沒有重新分配函數。 當然,不可能與realloc()完全相同,因為簡單地復制內存不適用於非聚合類型。 但是,比如說,這個函數會不會有問題:

bool reallocate (pointer ptr, size_type num_now, size_type num_requested);

在哪里

  • ptr之前為num_now對象分配了相同的分配器;
  • num_requested >= num_now ;

和語義如下:

  • 如果分配器可以將ptr處的給定內存塊從num_now對象的大小num_nownum_requested對象,它num_requested (留下未初始化的額外內存)並返回true
  • 否則它什么都不做並返回false

當然,這不是很簡單,但據我所知,分配器主要用於容器,而容器的代碼通常已經很復雜了。

給定這樣的函數, std::vector可以如下增長(偽代碼):

if (allocator.reallocate (buffer, capacity, new_capacity))
  capacity = new_capacity;     // That's all we need to do
else
  ...   // Do the standard reallocation by using a different buffer,
        // copying data and freeing the current one

不能完全改變內存大小的分配器只能通過無條件return false;實現這樣的功能return false; .

是否有如此少的具有重新分配能力的分配器實現,以至於不值得打擾? 還是我忽略了一些問題?

來自: http : //www.sgi.com/tech/stl/alloc.html

這可能是最有問題的設計決策。 提供一個重新分配的版本可能會更有用一些,該版本可以在不復制的情況下更改現有對象的大小或返回 NULL。 這將使其直接適用於具有復制構造函數的對象。 在原始對象未完全填充的情況下,它還可以避免不必要的復制。

不幸的是,這將禁止使用 C 庫中的 realloc。 這反過來又會增加許多分配器實現的復雜性,並使與內存調試工具的交互更加困難。 因此我們決定反對這種選擇。

這實際上是 Alexandrescu 用標准分配器指出的一個設計缺陷(不是運算符 new[]/delete[],而是最初用於實現 std::vector 的 stl 分配器,例如)。

realloc 的發生速度明顯快於 malloc、memcpy 和 free。 但是,雖然可以調整實際內存塊的大小,但它也可以將內存移動到新位置。 在后一種情況下,如果內存塊由非 POD 組成,則所有對象都需要在重新分配后銷毀和復制構造。

標准庫需要適應這種可能性的主要事情是作為標准分配器公共接口的一部分的重新分配函數。 像 std::vector 這樣的類當然可以使用它,即使默認實現是 malloc 新大小的塊並釋放舊塊。 它需要是一個能夠銷毀和復制構造內存中的對象的函數,但如果這樣做,它就不能以不透明的方式處理內存。 那里涉及到一些復雜性,需要更多的模板工作,這可能是標准庫中省略它的原因。

std::vector<...>::reserve 是不夠的:它解決了可以預期容器大小的不同情況。 對於真正可變大小的列表,realloc 解決方案可以使像 std::vector 這樣的連續容器更快,特別是如果它可以處理內存塊成功調整大小而不移動的 realloc 情況,在這種情況下,它可以省略調用 copy內存中對象的構造函數和析構函數。

您所要求的本質上是vector::reserve作用。 如果沒有對象的移動語義,就無法在不進行復制和銷毀的情況下重新分配內存和移動對象。

我想這是上帝出錯的地方之一,但我懶得寫信給標准委員會。

數組分配應該有一個重新分配:

p = renew(p) [128];

或類似的東西。

由於 C++ 的面向對象性質,以及包含各種標准容器類型,我認為這只是與 C 相比,對方向內存管理的關注較少。我同意在某些情況下 realloc() 會很有用,但解決這個問題的壓力很小,因為幾乎所有產生的功能都可以通過使用容器來獲得。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM