C ++不会告诉你动态数组的大小。 但为什么?

我知道在C ++中没有办法获得动态创建的数组的大小,例如:

int* a;
a = new int[n];

我想知道的是:为什么? 人们是否在C ++规范中忘记了这一点,或者是否存在技术原因?

这些信息是否存储在某个地方? 毕竟,这个命令

delete[] a;

似乎知道它有多少内存释放,所以在我看来, delete[]有知道的大小某种方式a


您经常会发现内存管理器将仅分配一定数量的空间,例如64个字节。

所以,你可能会要求新的int [4],即16个字节,但内存管理器将为你的请求分配64个字节。 为了释放这个内存,它不需要知道你要求多少内存,只需要它分配给你一个64字节的块。

接下来的问题可能是,它能否存储所需的尺寸? 这是额外的开销,并非每个人都愿意付费。 例如Arduino Uno只有2k的RAM,在这种情况下,每个分配4个字节突然变得很重要。

如果你需要这个功能,那么你有std :: vector(或等价的),或者你有更高级的语言。 C / C ++的设计目的是使您能够尽可能少地使用开销,这只是一个例子。


这是从“不支付你不需要的东西”这一基本规则中得出的结论。 在你的例子中delete[] a; 不需要知道数组的大小,因为int没有析构函数。 如果你写过:

std::string* a;
a = new std::string[n];
...
delete [] a;

然后, delete必须调用析构函数(并且需要知道要调用多少) - 在这种情况下, new函数必须保存该计数。 然而,由于它不需要在任何场合保存,Bjarne决定不允许访问它。

(事后看来,我认为这是一个错误...)

即使使用int ,事情必须知道分配内存的大小,但是:

  • 为了对齐和便利的原因,许多分配器将大小凑成一些方便的倍数(比如64字节)。 分配器知道一个块的长度是64字节 - 但它不知道这是否是因为n是1 ...或16。

  • C ++运行时库可能无法访问分配块的大小。 例如,如果newdelete正在使用malloc并且是free的,那么C ++库无法知道malloc返回的块的大小。 (通常当然, newmalloc都是同一个库的一部分 - 但并不总是如此。)


  • 一个根本的原因是指向T的动态分配数组的第一个元素的指针与指向任何其他T的指针没有区别。

    考虑一个虚构的函数,它返回一个指针指向的元素的数量。
    我们称之为“大小”。

    听起来很不错,对吧?

    如果不是因为所有的指针都是相同的:

    char* p = new char[10];
    size_t ps = size(p+1);  // What?
    
    char a[10] = {0};
    size_t as = size(a);     // Hmm...
    size_t bs = size(a + 1); // Wut?
    
    char i = 0;
    size_t is = size(&i);  // OK?
    

    你可能会争辩说第一个应该是9 ,第二个10 ,第三个9和最后1 ,但为了完成这个,你需要在每一个对象上添加一个“大小标记”。
    char在64位机器上需要128位的存储空间(因为对齐)。 这比所需要的多十六倍。
    (以上,十个字符的数组a需要至少168个字节。)

    这可能很方便,但也是不可接受的昂贵。

    当然,如果参数真的是指向默认operator new的动态分配的第一个元素的指针,您当然可以设想一个定义良好的版本,但这不像人们想象的那么有用。

    链接地址: http://www.djcxy.com/p/18579.html

    上一篇: C++ doesn't tell you the size of a dynamic array. But why?

    下一篇: C++ replacement for C99 VLAs (goal: preserve performance)