我知道的對象大小跟蹤的兩種主要方法隱含在大小分離的分配器中,其中的元數據位於旁邊(例如Kingsley樣式的分配器),或者將對象前面的大小定爲一個對象頭文件(例如dlmalloc)。一個非常糟糕的第三個解決方案是維護每個分配對象的地圖及其大小。那張地圖當然會由另一個分配器來管理。
我認爲你是在正確的軌道上,並且你很瞭解對齊方面的考慮因素。我試圖查找有關mt_alloc的一些信息,以查看是否有其他選擇或意外,但這些信息似乎並不容易。一些分配器有一個方法來查詢對象的大小(這可能或不便宜)。如果deallocate函數需要顯式地傳遞大小,那麼我猜想沒有這樣的函數存在,但你永遠不知道。
如果對齊很重要,你的計算需要稍微調整一下,因爲分配器可能不會返回適合你的內存。如果你一無所知返回指針的定位,你需要的東西,如:
struct object_header {
size_t size;
};
void * buf = xxmalloc (2 * alignment + size + sizeof(object_header));
void * alignedPtr = (void *) (((size_t) buf + sizeof(object_header) + alignment - 1) & ~(alignment - 1));
如果mt_alloc無法容忍內部指針釋放的對象,那麼這個計劃,因爲通過填充出來對準額外的空間提出你的問題,你不再知道返回給你的原始地址。在這種情況下,您可能需要在標題中存儲額外的字段。
根據mt_alloc在內部管理內存的方式,添加額外的頭文件也會給您帶來很大的開銷。在大小獨立的分配器中,加上這個頭文件可以使您在達到頁面大小的對象上最多支持2倍的空間開銷,在這一點上,您可以支付每個對象額外頁面的成本。在其他分配器中,這可能不是問題,但需要注意。
請記住,容器以越來越大的塊來分配內存,並且在容量減小時儲存它所擁有的內存。您的C庫可能不會有相同的使用模式,所以您甚至可能看不到與容器相同的性能改進。 –
@Emile:我想要跟蹤的大小是分配額外的空間來存儲組塊大小_inin_大塊。因此,如果請求了n個字節,請分配類似n + sizeof(std :: size_t)(+ - 對齊注意事項)的內容,並返回基地址+ sizeof(std :: size_t)。釋放指針p時,取p - sizeof(std :: size_t),讀取大小並將其傳遞給deallocate()。 – bluescarni
是的,當我讀到你的問題時,我不知何故錯過了。必須是ADD。 :-) –