程序猿c++(2) 内存空间 new&delete

  • A+
所属分类:C++

内存分配时机

程序猿c++(2) 内存空间 new&delete

在进入大括号前,会将大括号中需要的内存全部分配好,但是,构造函数只有在对象被实例化的时候才被调用

内存分配顺序

1、分配内存空间

2、调用构造函数

3、调用析构函数

4、回收内存空间

实例化方式

int main()
{
  A a(1);  //栈中分配
  A b = A(1);  //栈中分配
  A* c = new A(1);  //堆中分配
  delete c;
  return 0;
}

第一种和第二种没什么区别,一个隐式调用,一个显式调用,两者都是在进程虚拟地址空间中的中分配内存,而第三种使用了new,在中分配了内存。栈中内存的分配和释放是由系统管理,而堆中内存的分配和释放必须由程序员手动释放

动态内存原理

程序猿c++(2) 内存空间 new&delete

动态分配内存时,空间在堆中分配,但同时,会维护一张表格,该表格中记录了堆中内存的地址和该空间大小。如 int *p = new int;int的大小为4个字节,所以表中中产生一条记录,记录大小为4个字节,并指向堆中内存。 int *a = new int[10],则会开辟40个字节大小的空间,并记录在表格中。调用了new动态开启内存,必须调用delete手动释放内存,delete的方式有两种:delete a和delete [] a。如果new时使用了[ ],则delete的时候也必须加[ ]。下面以Student类为例进行讲解,Student对象的空间大小为16字节。

Student *q = new Student();//开辟了一个16个字节的空间,并在表中记录了大小及地址

Student *r = new Student[10];//开辟了160个字节的空间,并在表中记录了大小及地址

delete q;//在表中寻找和q相等的记录,首先根据q的类型调用相应的析构函数,再去记录中找到相应的大小和地址,回收所有内存

delete r;;//在表中寻找和q相等的记录,首先根据q的类型调用相应的析构函数,再去记录中找到相应的大小和地址,回收所有内存;但是,只会对第一个Student 对象调用析构函数,后面9个Student 对象不会调用析构函数,并且程序会报错。

delete [] r;;//在表中寻找和q相等的记录,首先根据q的类型调用相应的析构函数,再去记录中找到相应的大小和地址,回收所有内存;会对所有的Student 对象都调用析构函数

上图中,有句代码,a++;delete[] a;

由于先调用了a++,导致a的地址和表格中存储的地址不一样,也就导致了delete过程中匹配记录的时候无法找到相应的记录,也就无法回收内存,程序会报错。

delete使用的注意事项

程序猿c++(2) 内存空间 new&delete

代码测试

ps,大家最好手写代码试验下

程序猿c++(2) 内存空间 new&delete

程序猿c++(2) 内存空间 new&delete

程序猿c++(2) 内存空间 new&delete

三个文件分别如上,如果将main文件中的第20行代码,改成delete [] p; 结果如下,发现后构造的对象最先被delete。

程序猿c++(2) 内存空间 new&delete

如果改成delete  p;报错,结果如下,并报错。

程序猿c++(2) 内存空间 new&delete

Qt大课堂-QtShare

发表评论

您必须登录才能发表评论!