0%

专题知识5:内存相关

2020年4月8日 上午11:51

专题知识点3:constconst是存储在.text的常量区

new/delete与malloc/free的区别是什么

  1. 首先,new_delete是C++的关键字,而malloc_free是C语言的库函数,
  2. malloc不会调用构造函数和析构函数:
    1. 需要给定申请内存的大小,返回的指针需要强转。
  3. new会调用构造函数
    1. 不用指定内存大小,返回的指针不用强转。

什么是memory leak,也就是内存泄漏

  1. 内存泄漏(memory leak)是指由于疏忽或错误造成了程序未能释放掉不再使用的内存的情况。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,失去了对该段内存的控制,因而造成了内存的浪费。

内存泄漏的分类:内存泄漏的常见原因

  1. 堆内存泄漏 (Heap leak)。
    1. 对内存指的是程序运行中根据需要分配通过malloc,realloc new等从堆中分配的一块内存,再是完成后必须通过调用对应的 free或者delete 删掉。如果程序的设计的错误导致这部分内存没有被释放,那么此后这块内存将不会被使用,就会产生Heap Leak.
  2. 系统资源泄露(Resource Leak)。
    1. 主要指程序使用系统分配的资源比如 Bitmap,handle ,SOCKET等没有使用相应的函数释放掉,导致系统资源的浪费,严重可导致系统效能降低,系统运行不稳定。
  3. 没有将基类的析构函数定义为虚函数。
    1. 当基类指针指向子类对象时,如果基类的析构函数不是virtual,那么子类的析构函数将不会被调用,子类的资源没有正确是释放,因此造成内存泄露。
  4. 专题知识点1:指针专题smart_ptr也可以引起内存泄漏

C++的内存管理是怎样的?

  1. 在C++中,虚拟内存分为代码段、数据段、BSS段、堆区、文件映射区以及栈区六部分。
  2. 代码段:
    1. 包括只读存储区和文本区,其中只读存储区存储字符串常量,文本区存储程序的机器代码。
  3. 数据段:
    1. 存储程序中已初始化的全局变量和静态变量
  4. Bss 段:
    1. 存储未初始化的全局变量和静态变量(局部+全局),以及所有被初始化为0的全局变量和静态变量。
  5. 堆区:
    1. 调用new_malloc函数时在堆区动态分配内存,同时需要调用delete_free来手动释放申请的内存。
  6. 映射区:
    1. 存储动态链接库以及调用mmap函数进行的文件映射
  7. 栈:
    1. 使用栈空间存储函数的返回地址、参数、局部变量、返回值

函数在main函数执行前先运行

  1. 在 .text之前:data段的内容:
    1. 全局对象的构造函数会在main 函数之前执行。
    2. 一些全局变量、对象和静态变量、对象的空间分配和赋初值就是在执行main函数之前,而main函数执行完后,还要去执行一些诸如释放空间、释放资源使用权等操作
  2. 在 .text之前:.bss段的内容
    1. 进程启动后,要执行一些初始化代码(如设置环境变量等),然后跳转到main执行。全局对象的构造也在main之前。
  3. 通过关键字attribute,让一个函数在主函数之前运行,进行一些数据初始化、模块加载验证等。

Main函数执行之前,主要就是初始化系统相关资源:

C语言深度总结全面认识main函数之前运行代码 - 简书

  1. 设置栈指针
  2. 在 .text之前:data段的内容:
    1. 初始化static静态和global全局变量
  3. 在 .text之前:.bss段的内容
    1. 将未初始化部分的赋初值:数值型short,int,long等为0,bool为FALSE,指针为NULL,等等
  4. .text段:
    1. 将main函数的参数,argc,argv等传递给main函数,然后才真正运行main函数