【发布时间】:2016-03-17 01:02:17
【问题描述】:
我正在用 C++ 编写自己的内存系统(出于性能原因、附加调试信息以及分配 16 字节对齐的内存),我遇到了new[] 的问题。
似乎调用new[] 会导致分配额外的 4 个字节来指示数组中的元素数量,这会导致所有后续对象的对齐失效。所以我的问题是:
有没有办法通过编译器标志、pragma 声明等来关闭这 4 个额外字节的使用?
这是一个例子:
// Matrix class has to be 16-byte aligned
Matrix* transforms = new( matrixHeap, ALIGN_16, __FILE__, __LINE__ ) Matrix[31];
transforms[0] = Matrix::Identity;
查看 Visual Studio 2013 调试器时,我看到了以下值:
returned by new 0x0F468840
transforms 0x0F468844
最后,我看看原始内存,我看到了:
0x0F468840 1F 00 00 00
0x0F468844 01 00 00 00
******40 处的内存不是transforms[0] 中预期的第一个值。相反,它包含值31。这意味着矩阵只有 4 字节对齐。有什么办法可以关闭数组大小的业务,让transforms[0] 的第一个字节最终出现在 new[] 返回的地址中?
这是我的运营商new[]的重要部分:
void* operator new[] ( size_t size, Heap* heap, uint32_t alignment, char* file, int lineNumber )
{
size_t alignedSize = size + alignment - 1;
void* unalignedPtr = heap->Allocate( alignedSize );
void* alignedPtr = (void*) (((size_t) unalignedPtr + alignment - 1) & ~(alignment - 1));
return alignedPtr;
}
【问题讨论】:
-
C++ 需要知道分配数组的大小。这是语言的一个基本方面。尽管 C++ 没有指定必须以这种方式完成,但这是一种常见的方法。尝试编写自定义容器分配器,而不是
new分配器。 -
我不确定我是否理解您所描述的对齐问题。 C++ 要求
new返回的内存必须符合对象的对齐要求。 -
好吧,我编写了自定义的 new 和 new[] 运算符来替换现有的运算符,并确保我的运算符返回的内存与我创建的结构所需的对齐方式一致。我的问题是 C++ 似乎只是神奇地改变了返回值。
-
冗余字节可能被用作保护。这还提供了有关您分配的内存的“元数据”。
-
好吧,这很丑,但我想我别无选择,只能用 malloc 样式的版本替换我的 new[] 调用。
标签: c++ memory visual-studio-2013 new-operator