对c++内存释放感到困惑
Confused about C++ memory deallocation
所以在c++中如果我用new
创建一个对象我应该总是用delete
来释放它
例如
Segment::Segment(float length)
{
segmentLength = length;
angle = 0.0f;
x = Rand::randFloat(1.0f, 1.5f);
y = Rand::randFloat(1.0f, 1.5f);
vx = Rand::randFloat(0.0f, 1.0f);
vy = Rand::randFloat(0.0f, 1.0f);
prevX = Rand::randFloat(0.0f, 1.0f);
prevX = Rand::randFloat(0.0f, 1.0f);
};
假设我在另一个类中这样使用比如
this._segmentObject = Segment(2.0f);
this._segmentPointer = new Segment(2.0f);
在该类的析构函数中,我知道应该在this上调用delete
。_segmentPointer,但是我如何确保内存被释放为另一个? 然而,我如何确保内存被释放给另一个?
是自动的。这就是为什么这种类型的存储被称为自动。自动存储在存储生命周期结束时释放,并调用对象的析构函数。
当程序控制离开分配对象的作用域时,对象生命周期结束。
未分配new
, new[]
或malloc
族的对象应在对象超出作用域时销毁并"释放"。
通常这仅仅意味着代码已经到达了声明它的块的末尾,或者它所在的对象被(以某种方式或其他方式)销毁了。
要查看实际操作,您可以这样做:
struct C {
C() { std::cout << "C()" << std::endl; }
~C() { std::cout << "~C()" << std::endl; }
};
struct B {
B() { std::cout << "B()" << std::endl; }
~B() { std::cout << "~B()" << std::endl; }
private:
C c_;
};
struct A {
A() { std::cout << "A()" << std::endl; }
~A() { std::cout << "~A()" << std::endl; }
};
int main() {
B *b = new B; // prints "B()", also constructs the member c_ printing "C()"
{ // starts a new block
A a; // prints "A()";
} // end of block and a's scope, prints "~A()"
delete b; // prints "~B()", also destructs member c_, printing "~C()"
}
注意:如果我们不执行delete b
,"~B()"answers"~C()"将永远不会打印。同样地,如果c_
是分配给new
的指针,那么它需要是delete
'd才能输出"~C()"。"
内存。_segmentObject是包含对象的内存的一部分,当包含对象被销毁时,它将被释放。
。_segmentObject是从一个临时对象分配的,该对象是在堆栈上创建的,当它超出作用域时被删除。
不仅如此,您应该只在构造函数或析构函数中使用new进行分配,使用delete进行deallocate,否则如果抛出异常,您的程序可能会泄漏。
所有类类型成员对象的析构函数都在主类析构时调用。因此,在堆栈上分配的this
对象在超出作用域时将调用其析构函数。那时,this
对象的任何类类型成员对象都将有自己的析构函数被调用,而this
对象的析构函数将在成员指针上调用delete
。
#include <iostream>
using namespace std;
class A
{
public:
A() {}
~A() { cout << "Destructor for class A called" << endl; }
};
class B
{
private:
A a;
public:
B() {}
~B() { cout << "Destructor for class B called" << endl; }
};
int main()
{
B b;
return 0;
}
运行后,输出如下:
Destructor for class B called
Destructor for class A called
因此,您可以看到,当在堆栈上分配的b
在main
末尾超出作用域时,调用类B
的析构函数,在执行析构函数体之后,调用其任何类类型成员数据对象的析构函数,在这种情况下,这将意味着类A
的析构函数。因此,在您的示例中,指针将在this
类的析构函数中调用delete
,然后在this
的析构函数完成其析构函数体的执行之后调用_segmentObject
的析构函数。然后,一旦调用了非静态数据成员对象的所有析构函数,this
的析构函数就会返回。
_segmentObject是在堆栈上自动分配的。当变量超出作用域时,对象析构函数将被自动调用。
正如其他人所说,您不需要显式地做任何事情来回收this._segmentObject
使用的内存。一旦超出作用域,内存就会被回收。
不清楚为什么你会在两种方式中使用Segment
。您应该尝试确保使用资源获取是初始化的习惯用法,因为它消除了检查new
/delete
对的大部分需要。也就是说,只使用this._segmentObject
版本,而不使用指针。
- 释放错误后堆使用
- G锁定铸造到基础上会释放模拟行为
- 在将变量声明为引用时,堆在释放后使用
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 正在理解智能指针,但出现错误:未分配正在释放的指针
- C++双重释放或损坏(out)
- 如何在c++中释放内存
- 使用全局声明的向量时,C++双重释放错误/损坏
- 为什么这个 std::queue/指向结构的指针列表直到 List.Size() == 0 才释放内存?
- 为什么瓦尔格林德在不释放恶意内存后没有报告任何问题?
- 调用析构函数以释放动态分配的内存
- 在函数范围内在堆栈上分配的数组在离开函数时是否总是被释放?
- COM :是否可以查看是否存在对我的某个 COM 对象的进程外引用?我可以释放它吗?
- 如何在向量中释放指针?
- std::unordered_map析构函数不释放内存?
- 在C++中释放内存期间,迭代器与指针有何不同
- 包含矢量指针的结构的内存释放问题
- C++:在被本地字符串捕获后释放或销毁 malloc'd char *?
- 错误:malloc:对象 0x7f9edf504080 的 *** 错误:未分配正在释放的指针
- 如果分配数组引发异常,是否应该释放该数组