根据32位的Windows系统默认有2GB的用户空间,则不能new超过2GB的,执行下列代码:

double *p = new double[***];

会出现下面的错误

error C2148: 数组的总大小不得超过 0x7fffffff 字节

也就是说数组的总大小不能超过2GB,但实际上刚好小于2GB也是有问题,执行下列语句会出现下列错误

double *p = new double[**(* -)];

debug版本下报如下错误

release版本下报如下错误

并且release和debug模式下堆栈所能分配最大空间也是有区别,经测试release模式要额外需要120m左右的空间,dubug需要320M的空间,这些空间用于分配程序的代码段,静态区,进程和线程的默认堆栈,应该还有一些链接库,debug和release模式的区别可能是链接库的版本不一致,这是自己的理解,不确定对不对。

实际上new调的malloc,Windows上malloc调的HeapAlloc,HeapAlloc最后调的VirtualAlloc。
VirtualAlloc只能以比较大的单位(最小4KB)申请内存。HeapAlloc可以申请任意大小的内存。malloc基本上可以视为直接调用HeapAlloc(只是基本上)。new在调用malloc之后,如果是类会调用构造函数。

上面说的是堆,下面来说一下栈

每个线程都有一个独立的栈,默认大小是1M,栈主要用于存储局部变量和函数参数,例如在某一个函数A里调用另一个函数B,这两个函数里面的变量是共用一个栈,进入函数B时,B中的参数进行压栈操作,执行完毕返回时再出栈,这时如果参数内存过大或者递归调用过深,就会使压栈数据超出栈大小,造成栈溢出,在vs的debug模式下是这样的,但在release模式下分配超出栈大小数据却不会报错,并且实际内存也没有变化,好奇怪。

当然,我们可以修改栈空间的大小,vs中在属性->链接器->系统->堆栈保留大小可以修改,单位是字节,该值为0时表示默认1M的空间。

另外函数堆栈的清理方式决定了当函数调用结束时由调用函数或被调用函数来清理函数帧,在VC中对函数栈的清理方式由两种:

  参数传递顺序 谁负责清理参数占用的堆栈
__stdcall 从右到左 被调函数
__cdecl 从右到左 调用者

堆和栈的区别

1、内存空间

栈:在Windows下,栈是向低地址扩展数据结构,是一块连续内存区域。这句话意思是栈顶地址和栈最大容量是系统预先规定好,在WINDOWS下,栈大小是2M(也有说是1M,总之是一个编译时就确定常数),如果申请空间超过栈剩余空间时,将提示overflow。因此,能从栈获得空间较小。

堆:堆是向高地址扩展数据结构,是不连续内存区域。这是由于系统是用链表来存储空闲内存地址,自然是不连续,而链表遍历方向是由低地址向高地址。堆大小受限于计算机系统中有效虚拟内存。由此可见,堆获得空间比较灵活,也比较大。

2、分配速度

栈:只要栈剩余空间大于所申请空间,只需要移动栈顶指针就能完成分配,否则将报异常提示栈溢出。
堆:首先应该知道操作系统有一个记录空闲内存地址链表,当系统收到程序申请时,会遍历该链表,寻找第一个空间大于所申请空间堆结点,然后将该结点从空闲结点链表中删除,并将该结点空间分配给程序,另外,对于大多数系统,会在这块内存空间中首地址处记录本次分配大小,这样,代码中delete语句才能正确释放本内存空间。另外,由于找到堆结点大小不一定正好等于申请大小,系统会自动将多余那部分重新放入空闲链表中。

堆空间开辟需要用系统函数,栈上直接修改指针.

内存分配方式有三种:   
   
  
1.从静态存储区域分配。内存在程序编译时候就已经分配好,这块内存在程序整个运行期间都存在。例如全局变量,static变量。   
   
  
2.在栈上创建。在执行函数时,函数内局部变量存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器指令集中,效率很高,但是分配内存容量有限。
  
   
  
3.从堆上分配,亦称动态内存分配。程序在运行时候用malloc或new申请任意多少内存,程序员自己负责在何时用free或delete释放内存。动态内存生存期由我们决定,使用非常灵活,但问题也最多。

参考地址:http://www.cnblogs.com/yyxt/archive/2015/02/02/4268304.html

c++ new 堆 栈的更多相关文章

  1. java数据结构之(堆)栈

    (堆)栈概述栈是一种特殊的线性表,是操作受限的线性表栈的定义和特点•定义:限定仅在表尾进行插入或删除操作的线性表,表尾—栈顶,表头—栈底,不含元素的空表称空栈•特点:先进后出(FILO)或后进先出(L ...

  2. 堆”,"栈","堆栈","队列"以及它们的区别

    如果你学过数据结构,就一定会遇到“堆”,"栈","堆栈","队列",而最关键的是这些到底是什么意思?最关键的是即使你去面试,这些都还会问到, ...

  3. 堆,栈,内存管理, 拓展补充-Geekband

    8, 堆,栈,内存管理 栈:  local objects 在离开作用域之后就会被消除.  堆: new MyClass 一直会存在 静态对象: static local object    作用域在 ...

  4. 转:C/C++内存管理详解 堆 栈

    http://chenqx.github.io/2014/09/25/Cpp-Memory-Management/ 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了 ...

  5. 堆/栈的比较 以及 malloc/new动态内存的开辟

    堆与栈的比较:1.申请方式(1)栈(satck):由系统自动分配.(2)堆(heap):需程序员自己申请(c:调用malloc,realloc,calloc申请 free 来释放),并指明大小,并由程 ...

  6. java 堆 栈 常量池

    java 堆中保存new 出来的对象(每个对象都包含一个与之对应的class的信息,[class信息存放在方法区]),堆中分配的内存,有虚拟机的自动垃圾回收器管理,栈内存只对其所属线程可见. java ...

  7. java基础学习之"堆" "栈" "静态存储区" "方法区"

    引用部分 java中堆栈(stack)和堆(heap)(还在问静态变量放哪里,局部变量放哪里,静态区在哪里.....进来) Java堆.栈和常量池以及相关String的讲解 等我看完"深入理 ...

  8. 堆&栈的理解(转)

    (摘自:http://www.cnblogs.com/likwo/archive/2010/12/20/1911026.html) C++中堆和栈的理解 内存分配方面: 堆: 操作系统有一个记录空闲内 ...

  9. java 堆 栈 方法区的简单分析

    Java里的堆(heap)栈(stack)和方法区(method) 基础数据类型直接在栈空间分配, 方法的形式参数,直接在栈空间分配,当方法调用完成后从栈空间回收.   引用数据类型,需要用new来创 ...

  10. 堆&栈

    Java内存分为两种:堆内存和栈内存. 一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间.堆内存用于存放由new创建的对象和 ...

随机推荐

  1. C 二维数组,以及自定义二维数组

    C 二维数组,以及自定义二维数组 我们通常情况下是这样定义一个二维数组的: int a[10][15]; 我们分别查看一下a,a[0],*a 都是一样的值吧 我们可以这么理解: a是一个数组的数组 a ...

  2. Divisibility题解

    From lyh 学长 2018.5.3 信(liang)心(liang)杯T3 一道略弱的数论题. 题目描述 给定 n个数,问是否能从中选出恰好 k个数,使得这些数两两之差可以被 m 整除. 输入输 ...

  3. 成都Uber优步司机奖励政策(1月21日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  4. 用label实现横向瀑布流的方法

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAXcAAAKxCAIAAAAn+3udAAAKqWlDQ1BJQ0MgUHJvZmlsZQAASImVlg

  5. Python:numpy中的tile函数

    在学习机器学习实教程时,实现KNN算法的代码中用到了numpy的tile函数,因此对该函数进行了一番学习: tile函数位于python模块 numpy.lib.shape_base中,他的功能是重复 ...

  6. Android stado 运行项目,apk does not exist on disk.

    报错如下: 03/12 21:38:56: Launching iReader The APK file F:\git\iReader_nubia\iReader\build\outputs\apk\ ...

  7. CC3200底板测试-烧写CC3200-LAUNCHXL

    1. 拿到板子,先研究一下几个跳线帽的作用.我在底板上测到VCC_DCDC_3V3和VCC_BRD之间应该有一个跳线帽的,但是在原理上找不到. 2. LED灯的用途,测试的时候,发现这个灯有时候亮,有 ...

  8. javaweb(四)——Http协议(请求头,响应头详解)

    一.什么是HTTP协议 HTTP是hypertext transfer protocol(超文本传输协议)的简写,它是TCP/IP协议的一个应用层协议,用于定义WEB浏览器与WEB服务器之间交换数据的 ...

  9. Angualr6访问API

    参照 草根专栏- ASP.NET Core + Ng6 实战: https://v.qq.com/x/page/a0769armuui.html 1.environment.ts 添加apiUrlBa ...

  10. spark提交任务的两种的方法

    在学习Spark过程中,资料中介绍的提交Spark Job的方式主要有两种(我所知道的): 第一种: 通过命令行的方式提交Job,使用spark 自带的spark-submit工具提交,官网和大多数参 ...