2012-04-20 198 views
0

我將從上下文開始 - 我正在編寫內存管理子系統,爲此我提供了新[]的替代品/刪除[]運營商。我必須解決的問題之一是如何存儲由new []分配的數組的大小,以便delete []可以調用釋放對象上的析構函數。我選擇的解決方案是分配更多內存並在實際數組的第一個元素之前存儲數組的大小,並將指針返回給該元素。我想出了下面的代碼:將指向結構成員變量的(常規)指針轉換爲指向整個結構的指針

template<typename T, typename AllocatorType> 
T* NewArrayHelper(size_t count, AllocatorType* allocator, const char* file, int line) { 
    // Helper struct 
    struct Helper { 
     size_t Count; 
     T Array[1]; 
    }; 

    Helper* ptr = allocator->Allocate(sizeof(Helper) + sizeof(T)*(count-1), ALIGNOF(Helper), file, line); 

    // Call constructors, etc. ... 

    return &ptr->Array[0]; 
} 

我要指出,我喜歡這種方法是編譯器計算出的數組類型和size_t右對齊,我沒有做任何事情,除了讀書它並傳遞給分配器(ALIGNOF是一個宏)。此外,我不必做任何轉換工會或鑄造char *黑客必須有混淆問題等。

現在另一方面,我有刪除[]運營商的替換問題。即它傳遞了一個指向該結構內部的指針。

template<typename T, typename AllocatorType> 
void DeleteArrayHelper(T* ptr, AllocatorType* allocator, const char* file, int line) { 
    // Helper struct 
    struct Helper { 
     size_t Count; 
     T Array[1]; 
    }; 

    // Here ptr points to Array[0] in Helper struct 
} 

如何將這樣一個指針轉換爲指向整個結構的指針,這種方式的駭客最少並且可能是可移植的?

回答

0

像這樣的事情會工作,並應攜帶:

Helper *h = (Helper*)((uintptr_t)ptr - offsetof(Helper, Array[0])); 

uintptr_t通常是stdint.h