簡體   English   中英

delete []如何知道數組的大小?

[英]How does delete[] know the size of an array?

我很好奇delete []如何計算分配內存的大小。 當我做的事情:

int* table = new int[5];
delete[] table;

我明白表的內存是釋放的。 但是,如果我將指針重新分配給某個不同的表,會發生什么。

int* table = new [5];
int* table2 = new [9];
table = table2;
delete[] table;

我可以免費使用5或9號桌子嗎? 我對new []和delete []如何共享有關其大小的信息感興趣。 或許我錯過了一些必不可少的東西。

C ++ FAQ lite的第16.14節回答了這個問題:

有兩種流行的技術可以做到這一點。 這兩種技術都被商業級編譯器使用,兩者都有權衡,而且都不是完美的。 這些技術是:

 * Over-allocate the array and put n just to the left of the first Fred object. * Use an associative array with p as the key and n as the value. 

它會刪除一個大小為9的數組。它會刪除指針指向的數組。

未指定如何存儲大小信息,因此每個編譯器可以以不同的方式實現它,但是常見的方法是在數組之前分配額外的塊。 也就是說,當你這樣做時:

int* table = new int[5];

它實際上分配了一個由6個整數組成的數組,並將數組大小存儲在第一個元素中。 然后它返回指向第二個元素的指針。 所以要找到大小,刪除[]只需要讀表[-1],基本上。

這是一種常用的方法,但語言標准沒有規定必須以這種方式完成。 只是它必須工作

另一種方法可能是將數組的地址用作某個全局哈希表的鍵。 任何方法都有效,只要它產生正確的結果。

如何做到這一點是編譯器特定的細節。 但是,假設沒有內存損壞,刪除[]的調用將始終刪除正確數量的元素。 有幾種方法可以實現這一點,但一種簡單的方法是隱藏內存中的長度。

這是一個很好而簡單的方法來實現它以用於演示目的。 假設您的代碼調用new int [10]。 編譯器不分配10 * sizeof(int),而是分配(10 * sizefo(int))+ sizeof(size_t)。 然后它返回一個指向你的指針,它從頭開始偏移size_t。 在初始size_t空間內,它寫入數字10.現在,當您調用delete []並傳入指針時,編譯器只會向后移動size_t字節並找到要刪除的元素數。

delete []的工作方式與實現有關,但全局new運算符以某種方式將描述符與分配的內存相關聯(在大多數情況下,它預先分配給已分配的內存,或存儲在查找表中)。 描述符包含已分配的內存的實際大小。

在你的第二個代碼示例中,delete []將正確刪除int的九元素數組,並且原始的五元素數組將被泄露。

該機制是依賴於實現的,但是通過重新分配示例中的指針,它不會被“愚弄”。 它將釋放大小為9的數組,就像你告訴它一樣(在這種情況下會出現內存泄漏,因為大小為5的數組現在沒有任何指向它的內容)。

在new [] / delete []的情況下,內存方式與新/刪除情況相同/類似...大小信息存儲在(較大的)已分配塊本身內。 數組的有趣之處在於它還使用大小信息來知道調用析構函數的對象數量。

我的猜測是new []實際上分配的數據比看起來多。 它可能在返回的指針之前有幾個字節,它告訴數組中有多少項。

您可以想象系統將表的大小存儲在如下結構中:

struct MemoryAllocated
  {
  size_t sizeOfMemory;
  char* yourData;
  }

每種類型分配一些內存,系統返回一個指向'yourData'的指針。 每種類型的內存都是“空閑的”,系統會將指針移動到'sizeOfMemory'。 另請參見std :: allocator

暫無
暫無

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

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