代码之家  ›  专栏  ›  技术社区  ›  Lucas

delete[]如何知道数组的大小?

c++
  •  9
  • Lucas  · 技术社区  · 15 年前

    我很好奇delete[]是如何计算分配内存的大小的。当我做以下事情时:

    int* table = new int[5];
    delete[] table;
    

    int* table = new [5];
    int* table2 = new [9];
    table = table2;
    delete[] table;
    

    我能腾出一张5号或9号的桌子吗?我对new[]和delete[]如何共享有关其大小的信息感兴趣。或者也许我错过了一些重要的东西。

    8 回复  |  直到 6 年前
        1
  •  19
  •   Stack Overflow is garbage    15 年前

    它将删除大小为9的数组。 它删除指针指向的数组。

    未指定大小信息的存储方式,因此每个编译器可能以不同的方式实现它,但通常的方法是在数组之前分配一个额外的块。也就是说,当您这样做时:

    int* table = new int[5];
    

    它实际上分配了一个包含6个整数的数组,并将数组大小存储在第一个元素中。然后返回指向第二个元素的指针。所以要找到大小,delete[]基本上只需要读取表[-1]。

    这是一种常见的方法,但语言标准并没有具体说明这一点 必须 我们必须这样做。只是它必须 工作 .

    另一种方法可能是使用数组的地址作为某个全局哈希表的键。只要产生正确的结果,任何方法都是有效的。

        2
  •  17
  •   Doug T.    15 年前

    Section 16.14 C++的FAQ Lite回答了这个问题:

    有两种流行的技术 由商业级编译器使用, 完美的这些技术包括:

    * Over-allocate the array and put n just to the left 
      of the first Fred object.
    * Use an associative array with p as the key and n as the value.
    
        3
  •  4
  •   JaredPar    15 年前

    如何做到这一点是编译器特有的细节。但是,如果没有内存损坏,调用delete[],将始终删除正确数量的元素。有几种方法可以实现这一点,但一种简单的方法是将长度隐藏在内存中。

    这里有一个很好的简单的方法来实现这个演示。假设您的代码调用newint[10]。编译器不分配10*sizeof(int),而是分配(10*sizefo(int))+sizeof(size_t)。然后,它返回一个指向您的指针,该指针从起点开始偏移大小。在初始大小的空间中,它写入数字10。现在,当您调用delete[]并传入一个指针时,编译器只会向后调整字节大小并查找要删除的元素数。

        4
  •  2
  •   MattK    15 年前

    delete[]的工作方式取决于实现,但全局new运算符以某种方式将描述符与分配的内存相关联(在大多数情况下,它是在分配的内存之前,或存储在查找表中)。描述符包含分配的内存的实际大小。

    在第二个代码示例中,delete[]将正确删除int的九元素数组,而原来的五元素数组将被泄漏。

        5
  •  1
  •   Matthew Flaschen    15 年前

    该机制依赖于实现,但不会被您在示例中重新分配指针“愚弄”。它将释放大小为9的数组,就像您告诉它的那样(在本例中,将出现内存泄漏,因为大小为5的数组现在没有任何指向它的内容)。

        6
  •  0
  •   Robert Deml    15 年前

        7
  •  0
  •   Pierre    15 年前

    您可以想象,系统将表的大小存储在如下结构中:

    struct MemoryAllocated
      {
      size_t sizeOfMemory;
      char* yourData;
      }
    

    在分配内存时,系统会返回一个指向“yourData”的指针。

        8
  •  0
  •   mhk    11 年前

    在new[]/delete[]情况下,内存方面发生的情况与new/delete情况下发生的情况相同/相似。。。大小信息存储在(更大的)分配块本身中。数组有趣的是,它还使用大小信息来知道有多少对象需要调用析构函数。