“delete[] obj”和“delete obj”是如何在编译器级别实现的
how are `delete[] obj` and `delete obj` implemented at compiler level
可能的重复项:
为什么在删除中使用 [] (删除 [] ) 来释放动态分配的数组?
为什么C++仍然有一个删除[]和一个删除运算符?
我想知道它们有什么区别,我知道有些人可能会说的明显答案,一个是删除数组,另一个是删除单个对象,但我想知道为什么这两种操作应该有两种不同的删除方法?我的意思是删除基本上是使用 C free
方法实现的,该方法不在乎指针是否实际指向数组或单个对象。我能想到的唯一原因是两个能够知道它是否是一个数组并为每个单元格调用析构函数,而不仅仅是第一个对象,但这是不可能的,因为编译器无法猜测数组的长度只是看它的指针。顺便说一下,虽然据说它调用未定义的行为来调用delete
来分配new[]
内存,但我无法想象任何可能出错的事情。
正如您所发现的,编译器需要知道数组的长度(至少对于非平凡类型)才能为每个元素调用析构函数。对于这个 new[] 通常会分配一些额外的字节来记录元素计数,并返回一个指向此记账区域末尾的指针。
当你使用 delete[] 时,编译器将查看数组之前的内存以查找计数并调整指针,以便释放最初分配的块。
如果使用 delete
销毁动态分配的数组,则不会调用元素的析构函数(第一个除外),通常最终会尝试释放不指向已分配块开头的指针,这可能会损坏堆。
但这是不可能的,因为编译器无法猜测 数组的长度只看它的指针
那不是真的。编译器本身不需要猜测任何东西,但它确实会根据它看到的运算符决定调用哪个函数来释放内存。有一个单独的函数专门用于释放数组,并且该函数确实知道要释放的数组的长度,因此它可以适当地调用析构函数。
它知道数组的长度,因为通常new[]
分配包含数组长度的内存(因为这在分配时是已知的),并返回一个指针,指向分配的"可用"内存。当调用delete[]
时,它知道如何根据指向给定数组可用部分的指针访问此内存。
当你使用 new[]
分配内存时,编译器不仅需要构造每个元素,还需要跟踪已分配的元素数量。这是delete[]
正常工作所必需的。
由于new
和delete
在标量上运行,因此它们不需要这样做,并且可以节省一点开销。
绝对不需要new
与delete[]
兼容,反之亦然。将两者混合在一起是不确定的行为。
- 运算符C++ "delete []"仅删除 2 个前值
- g++用户定义的动态链接库上的全局new和delete运算符
- 如何在.obj文件上运行IlDasm?
- 为什么"delete"关键字不删除节点?
- "delete"在 C++ 中实际上做了什么?
- 如何使用Qt 3D库加载和显示搅拌机.obj源文件场景
- 析构函数和'delete'之间的区别
- 在 opengl 中渲染 obj 文件时出现黑窗口
- 如何知道何时调用删除以及何时调用 delete[] C++?
- 在对象指针上调用 Delete 是否会递归删除其动态分配的成员
- 体系结构x86_64的未定义符号:std:terminate(),typeinfo,运算符delete[],运算符new
- 析构函数中的"delete this"
- 为什么数组大小信息可用于"sizeof"运算符和 delete[] 运算符,但在将数组作为参数传递到
- 使用 Boost.Spirit 解析具有混合数据类型的 OBJ 文件?
- 正在读取 obj 文件!(指数)
- 即使在使用 delete[] 后仍保留的元素
- 我在主函数的左括号上不断收到错误,消息为obj\Debug\main.o||在函数"ZN11linked_listC1Ev"中:|
- float* 已在 Gameobject.obj 中定义
- 可执行文件C++包括.obj,.lib和.dll吗?
- “delete[] obj”和“delete obj”是如何在编译器级别实现的