2

In debug heap I can get size of array, which was created by new[]:

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

It is working correctly if the size of the array is less than 28 (but I don't know why? 0_0).

Does this trick working in release mode (not using debug heap)?

How I can get size of the array (100% working and stable)?

4

4 回答 4

11

You are relying on an implementation detail. That's how your particular implementation stores the size of the memory region where the array is placed. As you already see, the size of the memory region may be bigger than the size of the allocated array.

If you need to know the size of an array allocated with new[], you'll have to keep that value around.

于 2012-05-28T18:46:12.177 回答
7

Like this:

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

;)

It really is the best way what you are trying to do is take adavantage of something which is COMPLETELY compiler/library dependent ... Its a really bad thing to do, in general, as your code becomes completely unportable not even mentioning that the next version of your compiler may come with a different memory allocation implementation which breaks what you are trying to do ...

于 2012-05-28T18:45:57.083 回答
2

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

于 2012-05-28T18:48:26.280 回答
1

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

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

此外,您自己提到,如果数组大小小于某个阈值,则 16 字节数似乎不再有效。如果您分配的对象比您现在分配的任何对象都大,那么您可能必须走得更远才能达到大小。

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

  • 继续分配使用new[]并保持大小以供以后使用
  • 使用std::vector并获取大小使用std::vector::size
  • 如果事先知道数组的大小,并且不需要调整它的大小,请使用std::array. 请注意,此选项不会在堆上分配内存(当然除非您new自己std::array
于 2012-05-28T19:02:31.583 回答