c++ 堆栈和内存管理
stack(栈),heap(堆)
Stack:是存在于某作用域(scope)的一个内存空间(memory space)。例如当你调用函数,函数本身即会形成一个stack用来放置它所接收的参数,返回地址,及局部对象(local object)。
Heap:或称system heap,是指由操作系统提供的一块global内存空间,程序可动态分配(dynamic allocated)从中获得若干区域(blocks)。
stack objects的生命期
点击查看代码
class Complex { ... };
...
{
Complex c1(1,2);
}
static local objects的生命期
点击查看代码
class Complex { ... }
...
{
static Complex c2(1,2);
}
global objects的生命期
点击查看代码
class Complex { ... };
...
Complex c3(1,2);
int main()
{
...
}
heap objects的生命期
正确写法:
点击查看代码
class Comliex { ... };
...
{
Complex* p = new Complex;
...
delete p;
}
错误写法:
点击查看代码
class Complex { ... };
...
{
Complex* p = new Complex;
}
以上出现内存泄漏(memory leak),因为当作用域结束,p所指的heap object仍然存在,但指针p的生命却结束了,作用域之外再也看不到p。
new和delete
new:先分配memory,再调用ctor
new一个东西的过程为:先分配内存空间(memory),再转型,最后进行构造。
Complex* pc = new Complex(1,2);
编译器转换为:
Complex pc;
void mem = operator new( sizeof(Complex) ); //分配内存,其内部调用malloc(n)
pc = static_cast<Complex*>(mem); //转型
pc->Complex::Complex(1,2); //构造函数
1、在分配内存时,operator new是c++中一个特殊的带空格的函数,内部调用了malloc(n)函数。这步过后,pc会指向一个具有两个连续“double”类型大小的一段内存空间。
2、static_cast是类型转换函数,这一步在这里可以不必详究。
3、类型名(::后的Complex)和类名(::前的Complex)相同,可见这是个构造函数。pc指针指向这个构造函数,就是把这段内存空间内的值初始化为构造的值。由于成员函数都有一个隐藏的this指针指向调用他的对象,这一行代码应该用如下方式去理解:
pc->Complex::Complex(/this,/ 1, 2);//这里的this就是pc,返回pc这根指针
经过以上三步,new的操作就得以完成。
delete:先调用dtor,再释放memory
delete一个东西的过程为:先调用析构函数,后释放内存(memory)。
点击查看代码
String* ps = new String("Hello");
...
delete ps;
编译器转化为:
点击查看代码
String::~String(ps); //析构函数,释放指针所指的空间
operator delete(ps); //释放内存,释放指针;内部调用free(ps)
转载https://blog.csdn.net/qq_29821795/article/details/119619722