C++——数据存储


静态/动态内存分配

一个程序被加载到内存中,这块内存首先就存在两种属性:静态分配内存和动态分配内存。
静态分配内存:是在程序编译和链接时就确定好的内存。
动态分配内存:是在程序加载、调入、执行的时候分配/回收的内存。
在这里插入图片描述

数据存储

  • Text
      也称为代码段(Code),用来存放程序执行代码,同时也可能会包含一些常量(如一些字符串常量等)。该段内存为静态分配,这部分区域的大小在程序运行前就已经确定,并且内存区域属于只读。这块内存是共享的,当有多个相同进程(Process)存在时,共用同一个text段。

  • Data
      存放程序中已初始化的全局变量的一块内存区域。数据段也属于静态内存分配。
      data又可分为读写(RW)区域和只读(RO)区域。

    • RO段保存常量所以也被称为.constdata eg const数据
    • RW段则是普通非常全局变量,静态变量就在其中
  • Bss
      未初始化数据区,通常用来存放程序中未初始化的全局变量和静态变量的一块内存区域。BSS段属于静态分配,程序结束后静态变量资源由系统自动释放。

可执行程序在运行时又多出两个区域:栈区和堆区。

栈区和堆区

栈区

  由编译器自动释放,存放函数的参数值、局部变量等。每当一个函数被调用时,该函数的返回类型和一些调用的信息被存放到栈中。然后这个被调用的函数再为他的自动变量和临时变量在栈上分配空间。每调用一个函数一个新的栈就会被使用。栈区是从高地址位向低地址位增长的,是一块连续的内存区域,最大容量是由系统预先定义好的,申请的栈空间超过这个界限时会提示溢出,用户能从栈中获取的空间较小。

堆区

  用于动态分配内存,位于BSS和栈中间的地址区域。由程序员申请分配和释放。堆是从低地址位向高地址位增长,采用链式存储结构。频繁的malloc/free造成内存空间的不连续,产生碎片。当申请堆空间时库函数是按照一定的算法搜索可用的足够大的空间。因此堆的效率比栈要低的多。

  每个线程都会有自己的栈,但是堆空间是共用的。各区域的分布如下图:

在这里插入图片描述
例。A* a = new A; a->i = 10;在内核中的内存分配上发生了什么?

  1. 程序内存管理:
      解释data、text、bbs的意思。
  2. A* a = new A; a->i = 10:
  • A *a:a是一个局部变量,类型为指针,故而操作系统在程序栈区开辟4/8字节的空间(0x000m),分配给指针a。

  • new A:通过new动态的在堆区申请类A大小的空间(0x000n)。

  • a = new A:将指针a的内存区域填入栈中类A申请到的地址的地址。即*(0x000m)=0x000n。

  • a->i:先找到指针a的地址0x000m,通过a的值0x000n和i在类a中偏移offset,得到a->i的地址0x000n + offset,进行*(0x000n + offset) = 10的赋值操作,即内存0x000n + offset的值是10。

内存溢出和内存泄漏

1、内存溢出

指程序申请内存时,没有足够的内存供申请者使用。内存溢出就是你要的内存空间超过了系统实际分配给你的空间,此时系统相当于没法满足你的需求,就会报内存溢出的错误

内存溢出原因:

内存中加载的数据量过于庞大,如一次从数据库取出过多数据

集合类中有对对象的引用,使用完后未清空,使得不能回收

代码中存在死循环或循环产生过多重复的对象实体

使用的第三方软件中的BUG

启动参数内存值设定的过小

2、内存泄漏

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

内存泄漏的分类:

1、堆内存泄漏 (Heap leak)。对内存指的是程序运行中根据需要分配通过malloc,realloc new等从堆中分配的一块内存,再是完成后必须通过调用对应的 free或者delete 删掉。如果程序的设计的错误导致这部分内存没有被释放,那么此后这块内存将不会被使用,就会产生Heap Leak。

2、系统资源泄露(Resource Leak)。主要指程序使用系统分配的资源比如 Bitmap,handle ,SOCKET等没有使用相应的函数释放掉,导致系统资源的浪费,严重可导致系统效能降低,系统运行不稳定。

3、没有将基类的析构函数定义为虚函数。当基类指针指向子类对象时,如果基类的析构函数不是virtual,那么子类的析构函数将不会被调用,子类的资源没有正确是释放,因此造成内存泄露。

参考资料:

  1. C++——程序的内存结构
  2. 牛客网——C++工程师面试宝典
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页