2012-05-28 58 views
0

在调试堆我可以得到阵列,其通过new[]创建的尺寸:阵列的大小(新[])

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

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

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

我怎样才能得到数组的大小(100%的工作和稳定)?

+0

为什么你需要获得一个数组的大小? –

+2

您可以改用矢量。它的大小可以通过'std :: vector :: size()'来检索。 – chris

+2

[你无法做到这一点可靠/普遍](http://stackoverflow.com/questions/2405722/why-cant-you-access-the-size-of-a-newd-array)。 – DCoder

回答

7

像这样:

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

;)

这真的是你正在尝试做的最好的办法是采取的一些东西,完全是编译器/库依赖adavantage ......它真的一般来说,因为你的代码变得完全不可移植,甚至没有提到你的编译器的下一个版本可能带有不同的内存分配实现,这会破坏你正在尝试做的事情......

+2

-1我知道这应该是他应该做的,但你肯定不知道,他不是这么想的。另外,接收这样的答案真的很令人沮丧。 – Pubby

+0

@Pubby:增加了一点额外的解释为什么他试图做的很糟糕... – Goz

+2

+1当OP询问如何在脚下自己射击时,“瞄准更好”不是最好的答案。没有使用加载的枪,是。 –

10

你是依靠在一个impl上详细说明。这就是您的特定实现如何存储阵列所在的内存区域的大小。正如您已经看到的那样,内存区域的大小可能比分配数组的大小要大。

如果您需要知道以new[]分配的数组的大小,则必须保持该值。

2

任何涉及从CRT中挖掘东西的方法都是未定义的,并且无法100%工作。
你唯一的方法就是重载operator new [],它将存储定义的某个地方的大小,比如分配带有大小前缀的大对象。

+1

'任何涉及从CRT挖掘东西的方法都是未定义的......它不是*未定义*,它是*未指定*。如果它是前者,那么执行本身会有一段时间记录它分配的内存。 – Praetorian

1

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

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

另外,你自己提到,如果数组的大小小于某个阈值,16字节的数字就不再有效了。如果你分配的对象比你现在分配的任何对象都多,你可能需要更进一步才能达到规模。

因此,提供给您的解决方案是:

  • 继续使用new[]分配和使用std::vector::size
  • 保持一定的尺寸各地供以后使用
  • 使用std::vector并获得大小如果知道的大小该阵列事先,并且不需要调整它,使用std::array。请注意,这个选项不会在堆上分配内存(除非你自己newstd::array本身)