在 c++ 中应按什么顺序释放内存?
In what order should memory be deallocated in c++?
我在理解在C++中使用delete
运算符时应该发生的正确事件顺序有点困难。我已经内化了使用它的正确方法是当指针仍在引用点时。
在下面的示例中 - 我将数组的内容复制到temp
然后delete []
我的arrayPointer
指向的旧数组。
然后,我将arrayPointer
指向新创建的数组,并将不再需要的temp
设置为nullptr
。我想确保我不删除临时指针会导致内存泄漏。这还需要发生吗?
我问是因为我看过我们先指出nullptr
然后delete
的例子,但这似乎违反直觉。任何指导将不胜感激。谢谢!
template <class T>
void ValSet<T>::add(T elementToAdd){
if(!this->contains(elementToAdd)){
if(sizeOfArray == numOfElements){
sizeOfArray *= 2;
T* temp = new T[sizeOfArray];
for (int i = 0; i < numOfElements; i++)
temp[i] = arrayPointer[i];
delete [] arrayPointer;
arrayPointer = temp;
temp = nullptr;
}
numOfElements += 1;
arrayPointer[numOfElements-1] = elementToAdd;
}
}
正如您帖子的评论中所指出的,您的解决方案是正确的。
为了更详细地解释为什么您是正确的,您确保在复制和删除当前数据之前分配更多内存。这是唯一的顺序:保留(新数组),复制,取消保留(旧数组)。(无论如何,这就是我记得的方式。
更详细地说:temp
是一个指针,而不是数组本身。这是一个非常关键但经常被误解的观点。就我个人而言,我为此挣扎了很多。因此,当您简单地说T* temp;
时,您正在为当前帧中的指针分配空间。当你说T* temp = new T[size];
时,你正在为当前帧中的指针分配空间,并要求在内存中的其他地方提供更多空间(等于sizeof(T) * size
字节)。
这意味着temp
作为指针是一个局部变量,但它指向的不是。当你赋值arrayPointer = temp;
时,你说你的数据成员点在哪里temp
点,但它不等于temp
,因为它是一个局部变量。这就是为什么您要在将其分配给等于temp
之前delete[] arrayPointer
,否则您将永远无法回收arrayPointer
指向的内存。最后,当你说arrayPointer = temp;
时,内存中temp
指向的任何内容都不会被复制;只有temp
的(指针)值被复制到arrayPointer
(因此您必须将原始数组的成员显式复制到新数组中,而不是相反)。然后,当您的进程退出该帧时,所有本地声明的变量都会被释放,这就是为什么temp
作为指针消失,但它指向的内容没有被释放,因为它不在帧中(即使它是在帧中分配的)。
不过,有几个专业提示:我建议看看std::copy
而不是你的 for 循环,temp = nullptr;
实际上是多余的,因为分配给temp
的内存(作为局部变量)将在函数返回后被释放(如上所述)。
希望这在概念上有所帮助。但是,再说一遍:你绝对是对的:)
如果p
有值nullptr
,则delete p
什么都不做。
如果您看过人们将原始指针设置为 null 然后删除它的示例,那么这些示例就是糟糕的代码。
设置指向nullptr
的指针不会对它之前指向的基础内存执行任何操作 - 这是C++与大多数引用计数或垃圾回收语言之间的关键区别。
另一方面,有许多"智能指针"类实现引用计数语义;std::shared_ptr
是最著名的一个。所以也许你已经看到有人使用其中之一。对于这些,通常将指针重置为 null 会减少其引用计数,导致在引用计数为 1 时将其删除。但这将由班级处理;你不会自己打电话给delete
。
- CMake-按正确顺序将项目与C运行时对象文件链接
- 函数调用中参数的顺序重要吗
- 释放错误后堆使用
- 为什么不;名字在地图上是按顺序排列的吗
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 数到第n个楼梯的路(顺序无关紧要)
- G锁定铸造到基础上会释放模拟行为
- 优先顺序:智能指针和类析构函数
- 在将变量声明为引用时,堆在释放后使用
- 在循环中按顺序遍历成员变量
- 独立读取-修改-写入顺序
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- QML按钮点击功能执行顺序
- C++中数据类型修饰符的顺序
- 多个线程之间的获取-释放内存顺序
- 在 c++ 中应按什么顺序释放内存?
- 混合放松和释放获取内存顺序
- 获取释放内存顺序与顺序一致性不同的实际示例是什么?
- C++11 是否保证释放围栏和使用操作之间的内存顺序
- 静态变量释放顺序