将(常规)指针转换为struct的成员变量,指向整个struct

时间:2012-04-20 04:02:58

标签: c++ memory pointers memory-management

我将从上下文开始 - 我正在编写一个内存管理子系统,为此我提供了新的[] / delete []运算符的替代品。我必须解决的一个问题是如何存储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找出正确的对齐方式,除了读取它并传递给allocator之外我不需要做任何事情(ALIGNOF是一个宏那)。此外,我不需要执行任何强制转换或转换为不需要别名等问题的char * hacks。

另一方面,我有一个替换delete []运算符的问题。也就是说,它被传递给指向该结构内部的指针。

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
}

如何以最少的黑客方式将这样的指针转换为指向整个结构的指针,并且可能是可移植的?

1 个答案:

答案 0 :(得分:0)

这样的东西会起作用,应该是可携带的:

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

uintptr_t通常位于stdint.h