WDK 的数组标头大小(以C++为单位)

Header size of array in C++ for WDK

本文关键字:C++ 为单位 数组 WDK      更新时间:2023-10-16

不确定"header"是否是正确的术语,所以如果不是,请纠正我。

我尝试首先分配内存,然后使用重载(放置(new[] 运算符来初始化类对象数组(例如 MyClass(。

比如说,MyClass 对象的大小是0x68,我想要一个0x20数组。所以总大小是 sizeof(MyClass( * 0x20 = 0xD00,或者我是这么认为的。

现在当我使用我的重载放置 new[] 运算符时:

pArr = new(pAllocatedMem)MyClass[0x20];

返回size_t给 new[] 运算符的编译器实际上是0xD08。还有一个额外的 8 个字节。查看这 8 个字节的值,它用于存储数组的大小(在本例中为 0x20(。

那么,对于这个标头大小是否有一个恒定的定义,比如从 WDK 中,我可以使用它?此大小的变化取决于编译器还是其他什么?

该额外空间量(如果有(取决于编译器。 关于语言定义[新译,第15段]:

[It] 是一个非负的未指定值,表示数组分配开销;new-表达式的结果将从运算符 new[] 返回的值中偏移此量。

运行时通常使用它来了解最终在数组上调用delete时要销毁多少对象。

我自己补充答案。和同事做了一个小测试。如果要初始化的类具有定义的析构函数,则 VS 编译器将需要存储数组大小的开销。没有析构函数,没有开销。这是一个错误还是一个功能?!.

#include <malloc.h>
#include <new>
class Foo
{
public:
    //Foo() {}
    //~Foo() {} // <-- will cause overhead even with user-allocated memory passed to placement new()
    int a;
};
int main()
{
    int n = 0x10;
    size_t size = sizeof(int) * 2 + sizeof(Foo) * n;
    void* p = malloc(size);
    *((int*)p) = 0xaaaaaaaa;
    *(int*)((char*)p + size - sizeof(int)) = 0xbbbbbbbb;
    // Placement new with user-allocated memory
    Foo* pf = new ((char*)p + sizeof(int)) Foo[n];
    for (int i = 0; i < n; i++)
    {
        pf[i].a = i;
    }
    free(p);
    return 0;
}