【问题标题】:Converting a (regular) pointer to the member variable of a struct to pointer to the whole struct将指向结构成员变量的(常规)指针转换为指向整个结构的指针
【发布时间】:2012-04-20 04:02:57
【问题描述】:

我将从上下文开始 - 我正在编写一个内存管理子系统,为此我提供了 new[]/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 的正确对齐方式,除了读取它并将其传递给分配器(ALIGNOF 是一个宏那)。此外,我不必执行任何通过联合转换或转换为 char* 的黑客攻击,这些黑客必须解决别名问题等问题。

另一方面,我在替换 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
}

我怎样才能以最少的黑客攻击并且可能是可移植的方式将这样的指针转换为指向整个结构的指针?

【问题讨论】:

    标签: c++ memory pointers memory-management


    【解决方案1】:

    这样的东西会起作用,并且应该是可移植的:

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

    uintptr_t 通常在stdint.h

    【讨论】:

      猜你喜欢
      • 2015-01-24
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-29
      • 1970-01-01
      相关资源
      最近更新 更多