数组的大小(新[])

Size of array (new[])

本文关键字:数组      更新时间:2023-10-16

在调试堆中,我可以获取数组的大小,该数组由new[]创建:

int size = *((int *)((char *)ptr - 16));

如果数组的大小小于 28(但我不知道为什么?0_0),它工作正常。

这个技巧在发布模式下是否有效(不使用调试堆)?

如何获得阵列的大小(100% 工作且稳定)?

您依赖于实现细节。这就是您的特定实现存储放置数组的内存区域大小的方式。如您所见,内存区域的大小可能大于分配的数组的大小。

如果你需要知道分配new[]数组的大小,你必须保留这个值。

像这样:

std::vector< int > array( 1024 ); // allocate 1024 element array.
int size = array.size();
int sizeInBytes = size * sizeof( int );

;)

这确实是您尝试做的最好的方法是利用完全依赖于编译器/库的东西......一般来说,这是一件非常糟糕的事情,因为您的代码变得完全不可移植,甚至没有提到编译器的下一个版本可能会带有不同的内存分配实现,这会破坏您正在尝试执行的操作......

任何涉及从 CRT 挖掘某些内容的方法都是未定义的,不能 100% 工作。
您唯一的方法是覆盖运算符 new[],它将大小存储在定义的位置,例如分配带有大小前缀的较大对象。

正如其他人所提到的,您正在使用实现细节来确定分配数组的大小。您已经设法弄清楚,如果您从 new[] 返回的指针的开头向后退 16 个字节,您可以获得数组的大小。

16 字节的额外分配似乎过多,如果您编译应用程序的发布版本,则很可能不会出现这种情况。该实现可能会在您请求的长度之前和之后分配一些额外的字节,并用魔术值填充它,以帮助捕获代码超出数组边界的情况。此额外空间可能不会在发布版本中分配。

另外,您自己提到,如果数组大小小于某个阈值,则 16 字节数似乎不再有效。如果您分配的对象比现在分配的对象大,则可能必须向后退一步才能达到大小。

因此,您可以使用的解决方案是:

  • 继续使用 new[] 进行分配,并保持大小以供以后使用
  • 使用std::vector并使用std::vector::size获取大小
  • 如果事先知道数组的大小,并且不需要调整其大小,请使用 std::array 。请注意,此选项不会在堆上分配内存(当然,除非您new std::array本身)