根据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. Jetson tx2 串口通信

    主要参考了这篇博客:https://blog.csdn.net/zomb1e0117/article/details/85157014 其中需要注意的是最后的时候cutecom端口需要把设备改为:/d ...

  2. 使用 Linux 下的的logrotate进行日志的切割

    实际生产中,使用一个log文件来记录所有信息的话,一方面,时间过久,就会占用很大的空间:另一方面,就是一个文件记录对于后期日志的查看非常不利.为了解决查看了一下资料,发现linux里面有一个logro ...

  3. DBoW2 词袋模型笔记

    DBoW算法用于解决Place Recognition问题,ORB-SLAM,VINS-Mono等SLAM系统中的闭环检测模块均采用了该算法.来源于西班牙的Juan D. Tardos课题组. 主要是 ...

  4. cakephp2.x 多个应用程序公用一个核心类库

    环境Windows,apache,cake版本2.3.3 Cake项目路径 D:\wamp\www\Mycakephp 浏览器打开 http://localhost/Mycakephp 能够正常访问到 ...

  5. 回写盘写速度被限速为10M左右

    问题现像如下图所示: 用hd-speed等测试虚拟盘速度都能达到90M/s左右,但复制文件到虚拟盘速度最高只有10M/s 原因:由于客户机开机加载这个随机驱动和随机进程后,会对磁盘启动进程等有扫描检查 ...

  6. 【费元星原创】一键安装Hadoo2.7.6 集群完全分布式脚本-完美解决

    有Bug 欢迎反馈,我不烦:feiyuanxing@gmail.com 1 #!/bin/bash #@author:feiyuanxing [既然笨到家,就要努力到家] #@date:2017-01 ...

  7. Python :编写条件分支代码的技巧

    『Python 工匠』是什么? 我一直觉得编程某种意义是一门『手艺』,因为优雅而高效的代码,就如同完美的手工艺品一样让人赏心悦目. 在雕琢代码的过程中,有大工程:比如应该用什么架构.哪种设计模式.也有 ...

  8. 245. Subtree【LintCode java】

    Description You have two very large binary trees: T1, with millions of nodes, and T2, with hundreds ...

  9. Java基础知识:Java实现Map集合二级联动1

    Java实现Map集合二级联动 Map集合可以保存键值映射关系,这非常适合本实例所需要的数据结构,所有省份信息可以保存为Map集合的键,而每个键可以保存对应的城市信息,本实例就是利用Map集合实现了省 ...

  10. python3 SQLAlchemy模块使用

    更详细的操作介绍:https://www.imooc.com/article/22343 定义: SQLAlchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API之上,使用关系对 ...