delete[]操作符是否适用于通过指针返回的动态分配的内存?

Does the delete[] operator work with dynamically allocated memory returned through a pointer?

本文关键字:返回 指针 动态分配 内存 操作符 是否 适用于 delete      更新时间:2023-10-16

我想知道delete[]操作符如何处理函数返回的指针,而不是在与delete语句相同的范围内进行动态分配。假设我有一个简单的函数:

int *getArray()
{
    int *returnVal = new int[3];
    returnVal[0] = returnVal[1] = returnVal[2] = 0;
    return returnVal;
}

现在,当我需要在代码中使用该数组时,我将执行以下操作:

int *vals = getArray();
// use values...
delete[] vals;

然而,我想知道,c++编译器如何知道分配的内存块有多大(因此要从vals删除多少内存元素)?这是一种有效的技术吗?还是我必须单独删除每个数组值(就像下面的代码一样)?

int *vals = getArray();
// use values...
delete vals + 2;
delete vals + 1;
delete vals;

您应该只delete[]通过new[]获得的东西。在你的代码中,这是由getArray()返回的值。删除其他内容是非法的。

然而,我想知道,c++编译器如何知道有多大分配的内存块是。

每个实现都以某种方式存储分配的大小(我认为是类型)。

    一个常见的想法是存储记账信息(或索引)另一个想法是使用实际指针作为数据结构的键,该数据结构保存所需的信息

当然,这是过于简单的解释(它更像是对C的解释)。c++中增加了析构函数和诸如此类的细节

在new[]作用域中删除内存是完全可以的。在这里阅读更多内容,如果你懒得查看链接,这里是引用。

[16.14]在p = new Fred[n]之后,编译器如何知道在delete[] p期间有n个对象要被析构?

简短的回答:Magic.

长答案:运行时系统存储对象的数量n,在某个地方,如果你只知道指针p,它就可以被检索到。有两种流行的技术可以做到这一点。这两种技术都被商业级编译器使用,两者都有权衡,并且两者都不完美。这些技巧是:

  1. 过度分配数组并将n放在第一个Fred对象的左侧。
  2. 使用以p为键,n为值的关联数组

简短的回答:它有效。

实际上,从new[]获得的指针唯一有效的做法是指向delete[]它。

编译器将从操作系统获得的额外信息插入到内存中,以允许它跟踪分配的块有多大。此信息允许仅由指针标识的数据被正确地销毁和释放。

不能也不应该依次删除每个元素。你会得到未定义的结果。当分配内存时,编译器包含内务管理数据。