c++动态内存管理

c语言中使用malloc(进行动态开辟空间)、calloc(动态开辟空间,函数在返回前把内存初始化为0)、realloc(用于增容,用于修改一个原先已经分配的内存块大小)、free进行动态内存管理

c++通过new 和 delete动态管理内存
new/delete动态管理对象
new[]/delete[]动态管理对象组

void Test()
{
  int* p4=new int;     //动态分配4个字节(1个int)的空间
  int* p5=new int(3)   //动态分配4个字节(1个int)的空间并初始化为3
  int* p6=new int[3]   //动态分配12个字节(3个int)的空间
  delete p4;
  delete p5;
  delete[]p6;
}
newdelete:操作符  int:类型  (3):初始化为3   [3]:对象个数为3
 1. 对于内置类型:newmalloc本还没有区别
 2. 对于自定义类型:malloc动态开辟空间;new 动态开辟空间、调用构造函数(初始化)、调用析构函数(清理)

注意!malloc/free、new/delete、new[]/delete[],一定要匹配使用,否则可能出现内存泄漏的问题
c++动态内存管理_第1张图片

  1. 栈又叫堆栈:非静态局部变量、函数参数、返回值等等,栈是向下增长的
  2. 内存映射区:高效的I/O映射方式,用来装在一个共享的动态内存库
  3. 堆:用于程序运行时动态内存分配,堆是可以向上生长的
  4. 数据段:存储全局数据和静态数据
  5. 代码段:可执行的代码/只读常量

虚拟地址的好处:

  1. 保护物理地址
  2. 扩大空间,物理地址不够用
  3. 方便实现了父子进程的通信
static int a=10;
int b=10;
void func()
{
  static int c=10;
  int d=10;
  char* p1="hello";
  charp2[]="hello";
  int* p3=(int*)malloc(4);
  }  
NUL字节是字符串的终止符,但本身并不是字符串的一部分,字符串的长度不包括NUL
 1. strlen(p1)=5
 2. strlrn(p2)=5
 3. sizeof(p1)=48  p1为指针,在32平台为464为平台为8
 4. sizeof(p2)=6 数组的大小,包括/0

    A:栈(非静态局部变量,函数参数,返回值)   B:堆(动态内存分配)  C:数据段(全局数据和静态数据)  D:代码段(常量区)
    a  C 静态数据
    b  C 全局数据
    c  C 静态数据
    d  A 非静态局部变量
    p1 A 局部指针变量
    p2 A 局部数组
    p3 A 局部指针变量
    *p1 D
    *p2 A 
    *p3 B 动态内存分配    

malloc/free和new/delete的区别和联系?

  1. 都是动态管理内存的入口
  2. malloc/free是C/C++的标准库函数,new/delete是C++操作符
  3. malloc/free只是动态分配内存空间、释放空间(malloc只是开辟了与对象具有相同大小的内存块空间)。而new/delete除了分配空间还会调用构造函数和析构函数进行初始化与清理(new调用构造函数来创建对象)
  4. malloc/free需要手动计算类型大小且返回值为void*,new/delete可以自己计算类型的大小,返回对应类型性的指针
  5. malloc失败,返回0;new失败,抛出异常

new做了两件事:

  1. 调用operator new 分配空间
  2. 调用构造函数初始化对象

delete也做了两件事:

  1. 调用析构函数清理对象
  2. 调用operator delete释放空间

new[N]

  1. 调用operator new 分配空间
  2. 调用N次构造函数分别初始化每个对象

delete[N]
1. 调用N次析构函数清理对象
2. 调用operator delete释放空间

什么是内存泄漏:在堆上申请的空间没有释放
如何避免:良好的编程习惯,使用系统自带的工具(vs下crtdbg),自己实现检测工具,第三方检测工具

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