简体   繁体   English

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

[英]Converting a (regular) pointer to the member variable of a struct to pointer to the whole struct

I'll start with the context - I'm writing a memory management subsystem and for that I'm providing substitutes for new[]/delete[] operators. 我将从上下文开始-我正在编写一个内存管理子系统,并为此提供了new [] / delete []运算符的替代品。 One of the problems I had to solve was how to store the size of an array allocated by new[] so that delete[] can call destructors on deallocated objects. 我必须解决的问题之一是如何存储由new []分配的数组的大小,以便delete []可以在释放对象上调用析构函数。 My chosen solution was to allocate more memory and store the size of an array before the first element of an actual array and return the pointer to that element. 我选择的解决方案是分配更多的内存,并在实际数组的第一个元素之前存储数组的大小,然后将指针返回该元素。 I came up with the following code: 我想出了以下代码:

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];
}

I should mention that what I like about this approach is that the compiler figures out the right alignment for the array and size_t and I don't have to do anything except reading it and passing to allocator (ALIGNOF is a macro that does that). 我应该提到的是,我喜欢这种方法的原因是编译器为数组和size_t找出了正确的对齐方式,除了读取并传递给分配器外,我无需执行任何操作(ALIGNOF是执行此操作的宏)。 Also I do not have to do any cast-through-union or cast to char* hacks that have to problems with aliasing etc. 另外,我不必进行任何强制转换联盟或强制转换为具有别名等问题的char * hack。

Now on the other hand I have a problem with replacement for the delete[] operator. 现在,另一方面,我有一个替换delete []运算符的问题。 Namely it is handed a pointer to the internals of that struct. 即,将其传递给该结构内部的指针。

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
}

How can I convert such a pointer to the pointer to a whole struct in a manner that does the least hacking and is possibly portable? 我该如何以最少的黑客攻击并且可能是可移植的方式将这种指针转换为指向整个结构的指针?

Something like this will work, and should be portable: 这样的事情会起作用,并且应该可移植:

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

uintptr_t is usually in stdint.h . uintptr_t通常位于stdint.h

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM