【问题标题】:C++ force new[] to not allocate 4 additional bytesC++ 强制 new[] 不分配 4 个额外字节
【发布时间】: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


【解决方案1】:

由于它似乎始终使用 4 个字节作为大小,您可以安排您的 operator new[] 函数返回比 16 字节对齐的地址少 4 个。您仍然希望operator new 直接返回一个 16 字节对齐的地址。

【讨论】:

    猜你喜欢
    • 2017-11-28
    • 2012-11-24
    • 1970-01-01
    • 2021-12-20
    • 2012-09-13
    • 2012-06-25
    • 2015-05-22
    • 1970-01-01
    • 2015-02-24
    相关资源
    最近更新 更多