C++内存管理简述(一)

1.什么叫做堆和栈

存在某个作用域的一块内存空间,例如当你调用函数,函数本身随即会形成一个stack来房子它所接受的参数,以及返回的地址事实上在C++一个程序的过程序中,主函数先入栈,然后是各种调用的函数入栈,然后随着return,就出栈

也叫system heap,是由操作系统提供的一块global的空间,程序可以动态分配(dynamic allocated)从其中获得若干的区块
堆里面内存需要使用malloc或者new等语句来动态的分配,并且需要人手动的去释放它

stack object的生命周期

我们说只要一个变量离开了它所在的作用域,比如说下面的代码

class Complex{
    ...
}
...
{ //block2
   ...
   Complex c1(1,2);
   ...
}

第二个花括号就是代表c1这个变量的作用域,如果程序执行完了这个作用域,c1这个变量所占的空间就一并被回收了,这种object又被成为auto object

static local object

就是加了static关键字的代码,这个关键字就很厉害了,在变量之前加入这个关键字,这个关键字的生命周期实际上是早于当前当前这个static变量所在的作用域,结束之后依然存在,直到整个程序结束,这个static的变量才会消失

global objects的生命周期

如下面代码

class Complex{...}
...

Complex c3(1,2)

...
int main(int argc,char *argv[]){
    ...
}

这个变量c3就是global object,知道整个程序结束,它的生命周期才会结束,其作用域实际上是整个程序,它的存在甚至在main函数之前

heap objects的生命周期

代码如下

class Complex{...}
...
{
    complex* p=new Complex()
    ...
    delete p

}

所以heap object的生命周期就是delete的时候就终结束
注: 所谓内存泄漏就是在new出来之后没有delete掉这个开辟的内存,这块内存没有办法被操作系统回收

new这个语句是怎么回事

Complex *pc=new Complex(1,2)

事实上,在C++ 编译器里面,new这个语句是在先分配之后才会调用constructor,代码实际上是这样的

Complex *pc; //声明Complex的指针
void *mem=operator new(sizeof(Complex)); //分配内存 实际上还是调用的malloc
pc = static_cast(mem) //对void指针进行转型
pc->Complex::Complex(1,2) //调用Complex的构造函数
//事实上 Complex(1,2) -> Complex::Complex(pc,1,2) pc就是this指针

delete这个语句是怎么回事

直接上代码

Complex* pc=new Complex(1,2)
...
delete pc

实际上编译器把上面代码变成了这样

Complex::~Complex(pc); //先调用析构函数
operator delete(pc); //释放内存
//实际上delete在内部也是调用的free()这个函数

再来一次String的内存分配和释放

调用new的代码如下

String* ps=new String("Hello World");

编译器实际将其转化为了

String *ps;
void *mem=operator new(sizeof(String));
ps=static_cast(mem);
ps->String::String("Hello World");

调用delete的代码如下

String::~String(ps); //析构函数
operator delete(ps); //释放内存

除此之外

你还可以通过下面这个地址学习堆和栈

https://kb.cnblogs.com/page/501239/

你可能感兴趣的:(C++)