计算机内存管理

计算机存储区域

        在计算机中,存储区域主要分为:

  • 硬盘
  • 内存
  • 高级缓存
  • 寄存器

计算机内存管理_第1张图片
        他们的运行速率自下而上加快,与之相应的造价越高。其中,硬盘的运行效率最慢,寄存器的效率最快。

C++内存分区

        在C++ 中,内存主要分为五个区,分别是:

  • 代码区
  • 全局(静态)数据区
  • 栈区
  • 堆区

代码区

        代码区是用来储存程序的所有代码,以及字符串常量等在编译期间就能确定的值,在程序的整个生命周期内, 在常量数据区的数据都是可用的。在这个区域内,所有的数据都是只读的,不可以修改本区域的数据,之所以这样,是因为在实际的实现中,最底层内部存储格式的实现会使用特定的优化方案。比如说,编译器可能只把字符串常量存储一次,而在几个重叠的对象里面引用它。

全局(静态)数据区

        是用来存储全局静态变量的存储区域。只有在程序启动的时候才被分配,直到程序开始执行时才被初始化,比如:函数的静态变量就是在程序执行到定义该变量的代码时才被初始化的。在静态区数据区中没有被初始化的区域可以通过void*指针来访问或操纵,但是static定义的静态变量只能在本文件中使用,不可在其它文件中声明使用。

栈区

        栈区主要存放编译器在需要的时候自动分配,在不需要的时候自动销毁的变量。主要是局部变量和函数的参数等,在函数调用和传参的时候,编译器为局部变量或形参开辟空间,注意,在这块空间中,编译器并不会自动对它进行任何的初始化,它所保存的不是0,而是一个随机值(可能是该储存区上次被使用后的值),在函数结束后,所开辟的空间将自动销毁,里面所存的内容将不复存在,也就是释放存储区的内容。 这就是为什么老师们在讲课中,最喜欢用的字眼:参数压栈和弹出。

堆区

        堆区是一个动态的存储区域,使用库函数malloc()free(),和操作符newdelete以及一些相关变量来进行分配和回收,在堆区中,对象的生命周期可以比它存在内存中的生命周期短,换句话说:程序可以获得一片内存区域而不用马上对它进行初始化,同时,在对象被销毁后,也不用马上收回它所占用的内存区,在这段时间内,用户可以还可以用void*型的指针访问这片区域,但是原始对象的非静态区以及成员函数都不能被访问或者操纵,因为我们知道实际上对象已经不存在了。

全局(静态)数据、堆、栈空间的生命周期

计算机内存管理_第2张图片

new、delete实现机制

计算机内存管理_第3张图片

new []、delete []实现机制

计算机内存管理_第4张图片

malloc、free和new、delete的区别

  1. malloc开辟空间类型大小需手动计算,new是由编译器自己计算。
  2. malloc返回类型为void*,必须强制类型转换对应类型指针,new则直接返回对应类型指针。
  3. malloc开辟内存时返回内存地址要检查判空,因为若它可能开辟失败会返回NULLnew则不用判断,因为内存分配失败时,它会抛出异常bac_alloc,可以使用异常机制。
  4. 无论释放几个空间大小,free只传递指针,多个对象时delete需加[]
  5. mallocfree只是开辟空间并释放,newdelete则不仅会开辟空间,还调用构造函数和析构函数进行初始化和清理。
  6. newdelete底层是基于mallocfree来实现的,而mallocfree不能基于newdelete实现。
  7. 因为newdelete是操作符,它调用operator newoperator delete,它们可以被重载,在标准库里它有8个重载版本,而mallocfree不可以重载。
  8. 对于malloc分配内存后,若在使用过程中内存分配不够或太多,这时可以使用realloc函数对其进行扩充或缩小,但是new分配好的内存不能这样被直观简单的改变。
  9. 对于newdelete若内存分配失败,用户可以指定处理函数或重新制定分配器new_handler(可以在此处进行扩展),mallocfree用户是不可以处理的。
  10. malloc是在堆上分配内存的,但new其实不能说是在堆上,C++中,对new申请内存位置有一个抽象概念,它为自由存储区,它可以在堆上,也可以在静态存储区上分配,这主要取决于operator new实现细节,取决与它在哪里为对象分配空间。

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