c++内存

c++中内存分区

在C++中,内存分成5个区

内存区功能
由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区。里面的变量通常是局部变量、函数参数等。
C语言使用malloc从堆上分配内存,使用free释放已分配的对应内存。
自由存储区自由存储区是C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区。
全局/静态存储区全局变量和静态变量被分配到同一块内存中
常量存储区这是一块比较特殊的存储区,他们里面存放的是常量(const),不允许修改。

不同区域存放不同数据,赋予不同的生命周期,给我们更大的灵活编程

例子:
在这里插入图片描述

堆和栈

我们举一个例子:
void f() { int* p=new int[5]; }
这条短短的一句话就包含了堆与栈,看到new,我们首先就应该想到,我们分配了一块堆内存,那么指针p呢?他分配的是一块栈内存,所以这句话的意思 就是:在栈内存中存放了一个指向一块堆内存的指针p。在程序会先确定在堆中分配内存的大小,然后调用operator new分配内存,然后返回这块内存的首地 址,放入栈中。

堆和栈的区别:

  • 一、由以上综述就可以得知,他们程序的内存分配方式不同。
  • 二、申请和响应不同:
    1、申请方式:stack由系统自动分配,heap需要程序员自己申请,C中用函数malloc分配空间,用free释放,C++用new分配,用delete释放。
    2、申请后系统的响应:
    栈:只要栈的剩余空间大于所申请的空间,系统将为程序提供内存,否则将报异常提示栈溢出。
    堆:首先应该知道操作系统有一个记录内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请的空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样代码中的delete或free语句就能够正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会将多余的那部分重新放入空闲链表中。
  • 三、 申请的大小限制不同:
    栈:在windows下,栈是向低地址扩展的数据结构,是一块连续的内存区域,栈顶的地址和栈的最大容量是系统预先规定好的,能从栈获得的空间较小。
    堆:堆是向高地址扩展的数据结构,是不连续的内存区域,这是由于系统是由链表在存储空闲内存地址,自然堆就是不连续的内存区域,且链表的遍历也是从低地址向高地址遍历的,堆得大小受限于计算机系统的有效虚拟内存空间,由此空间,堆获得的空间比较灵活,也比较大。
  • 四、申请的效率不同:
    栈:栈由系统自动分配,速度快,但是程序员无法控制。
    堆:堆是有程序员自己分配,速度较慢,容易产生碎片,不过用起来方便。
  • 五、堆和栈的存储内容不同:
    栈:在函数调用时,第一个进栈的是主函数中函数调用后的下一条指令的地址,然后是函数的各个参数,在大多数的C编译器中,参数是从右往左入栈的,当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令。
    堆:一般是在堆得头部用一个字节存放堆得大小,具体内容由程序员安排。

堆空间和栈空间大小

我们知道,程序运行时在内存中主要有代码段、数据段、堆栈段(堆空间和栈空间)、进程头、动态链接库等区域。 其中数据使用到的:

数据段:静态内存空间,其中数据的总大小和初始值在编译时确定,数据在整个程序运行时一直存在。
栈空间:自动内存空间,其中数据的大小在编译时确定,数据的分配和释放也由编译器在函数进入和退出时插入指令完成,数据生命周期和函数一样。
堆空间:动态(手动)内存空间,其中数据的大小和初始值在运行时确定,数据生命周期不定。

  • 栈空间的大小初始值
    使用**命令ulimit(或limit)**输出一个栈限制:stack size (kbytes) 8192。 这说明Linux默认的用户栈空间的大小是8MB(软限制)。并且可以使用ulimit 命令临时改变当前shell下执行程序的栈空间。
  • 堆空间的大小初始值:默认是没有软限制的,只依赖硬限制。
  • 那操作系统能给栈空间的最大值(硬限制)是多少呢?需要看用户空间线性地址的分配, 记得Linux中栈空间的起始地址和堆空间的起始地址是固定的,并向对方方向增长, 那么栈空间和堆空间最大值总和应该就是这两个固定地址直接的内存大小。

1. 内存溢出

内存溢出 OOM (out of memory),是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个int,但给它存了long才能存下的数,那就是内存溢出。

2. 内存泄漏

内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。最终的结果就是导致OOM。
  内存泄漏是指你向系统申请分配内存进行使用(new),可是使用完了以后却不归还(delete),结果你申请到的那块内存你自己也不能再访问(也许你把它的地址给弄丢了),而系统也不能再次将它分配给需要的程序。
  
参考例子

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值