数组大小(new [])

时间:2012-05-28 18:43:55

标签: c++ arrays new-operator

在调试堆中,我可以获得由new[]

创建的数组大小
int size = *((int *)((char *)ptr - 16));

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

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

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

4 个答案:

答案 0 :(得分:11)

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

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

答案 1 :(得分:7)

像这样:

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

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

答案 2 :(得分:2)

任何涉及从CRT采矿的方式都是未定义的,不能100%工作 你唯一的方法是覆盖operator new [],它将存储大小定义的大小,比如分配带有大小前缀的更大的对象。

答案 3 :(得分:1)

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

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

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

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

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