大家都知道栈的地址按照从高到低的顺序增长的,

而堆的地址是按照从底到高的顺序增长的。

int *n1 = new int(1);
int *n2 = new int(2);
cout<<"n1,n2所指的地址:" << n1 << "  " << n2<<" " <<"相差:"<<(int)n1-(int)n2<<endl;
cout << "n1,n2的地址    :" << &n1 << "  " << &n2 <<" "<<"相差:"<< (int)&n1 - (int)&n2 << endl;
cout << sizeof(int*) << endl;

n1和n2是储存在栈上的

而它们所指的空间是位于堆上的

这里我发现在VS2013 debug模式下的结果是,n2和n1相差了12而不是8

观察内存布局我发现

n1和n2之间隔了很多cc,查阅后发现是为了越界之后,造成软中断方便调试之用的。运行下面的程序可以发现产生了一个中断(触发断点)

int main()
{//嵌入汇编//int表示触发软中断,3是中断号,//代码int 3在内存中刚好是一个字节CC__asm int 3;return 0;
}

切换到release下发现

n1和n2之间差的值变成了8

*这里n1比n2地址小的原因是

多核CPU经常会并行同时运行一些没有因果关系的语句,n2申请空间时没有使用n1的数据,编译器就可以优化成先申请n2,再申请n1,或先申请n1,再申请n2,或者两个并行同时申请(感谢群里的C++大神指点)。

可以看到栈的增长是按照从高到的低的顺序

而堆的增长是按照从低到高的顺序

同时我们也可以看成栈分配的内存是连续的

而堆的分配的内存是不连续的

哪我们有没有办法使堆的分配在两个连续的内存上呢?

方法是我们可以先分配一个大的内存

然后再这块内存上进行我们的操作

void *p1 = malloc(2 * sizeof(int));
void *p2=(int*)p1 + 1;
int *t1 = new (p1)int(1);
int *t2 = new (p2)int(2);
cout << "t1,t2所指的地址:" << t1 << "  " << t2 << endl;
cout << "t1,t2的地址    :" << &t1 << "  " << &t2 << endl;

我们先用malloc分配出一块大小为两个int的内存

这时p1指向这块内存的起点

我们再将p1移动int个大小的内存得到了p2

然后分别在p1和p2所指的地址上构建变量

这样就使的new出的两个变量在堆上的地址连续了

debug下

release下

栈(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。分配方式类似于数据结构中的栈。

堆(heap) — 由程序员分配释放, 若程序员不释放,程序结束时由OS回收 。分配方式倒是类似于链表。

int *t1 = new (p1)int(1) — 重载operator new 的一个标准、全局的版本,原型是void *operator new( size_t, void *p ) throw() { return p; }在p所指的地方分配内存

转载于:https://www.cnblogs.com/magicsoar/p/3631936.html

C++内存布局(1)-让new出的两个变量在堆上的地址连续相关推荐

  1. linux内存布局及页面映射

    在Linux系统中,以32bit x86系统来说,进程的4GB内存空间(虚拟地址空间)被划分成为两个部分 ------用户空间和内核空间,大小分别为0-3G,3-4G. 用户进程通常情况下,只能访问用 ...

  2. Linux 进程内存布局(一)

    Linux 进程内存布局 内存管理是操作系统的核心分部,对于程序员和系统管理员来说都非常重要. 这篇文章中我将以介绍一个运行在x86架构的32位Linux 操作系统上进程为例,介绍进程在执行的时候的内 ...

  3. JVM成神路对象内存布局、分配过程、从生至死历程、强弱软件引用

    引言 对象实例的角度,阐述一个Java对象从生到死的历程.Java对象在内存中的布局以及对象引用类型. 一.Java对象在内存中的布局 Java源代码中,使用new关键字创建出的对象实例,我们都知道在 ...

  4. ATF官方文档翻译(十一):ATF固件设计(Firmware Design)-BL图像的内存布局

    友友一起学习点赞关注不迷路!!! BL镜像的内存布局 每个引导程序镜像可以分为两部分: •镜像的静态内容.这些数据实际上存储在磁盘上的二进制文件中.在ELF术语中,它们被称为PROGBITS部分: • ...

  5. c++ string最大长度_关于C++ std::string类内存布局的探究

    一切要从探讨指针的类型说起. 运行环境:Ubuntu 20.04.1 LTS 64-bit 预先准备:调整字节对齐单位为1,防止为4时因填充导致人脑判断失误 #pragma pack(1) 01 - ...

  6. slub object 内存布局

    我在 https://blog.csdn.net/wowricky/article/details/83218126 介绍了一种内存池,它的实现类似于linux 中打开slub_debug (1. m ...

  7. 【C++】C++对象模型:对象内存布局详解(C#实例)

    C++对象模型:对象内存布局详解 0.前言 C++对象的内存布局.虚表指针.虚基类指针解的探讨,参考. 1.何为C++对象模型? 引用<深度探索C++对象模型>这本书中的话: 有两个概念可 ...

  8. 理解Java对象:要从内存布局及底层机制说起,话说....

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 前言 大家好,又见面了,今天是JVM专题的第二篇文章,在上 ...

  9. 多重继承和虚继承的内存布局

    这篇文章主要讲解虚继承的C++对象内存分布问题,从中也引出了dynamic_cast和static_cast本质区别.虚函数表的格式等一些大部分C++程序员都似是而非的概念.原文见这里 (By Eds ...

  10. JVM:对象的实例化、内存布局与访问定位

    对象的实例化 创建对象的方式 new关键字 最常见的方式 变形1:Xxx的静态方法(单例模式) 变形2:XxxBuilder/XxxFactory的静态方法 Class的newInstance() 反 ...

最新文章

  1. vue elementui el-select通过@Change触发事件
  2. div中插入图片_Web前端开发基础知识,设置网页背景图,如何在网页中插入图片...
  3. Windows 64 位 mysql 5.7以上版本包解压中没有data目录和my-default.ini以及服务无法启动的解决办法以及修改初始密码的方法...
  4. oracle 日志丢失,Oracle联机日志文件丢失解决方法一例
  5. 谷歌开源的 GAN 库--TFGAN
  6. Java内存溢出的情况
  7. 使用tf.data.Dataset.from_tensor_slices五步加载数据集
  8. 学习OpenCV研究报告指出系列(二)源代码被编译并配有实例project
  9. vue html5 picker,详解VUE-地区选择器(V-Distpicker)组件使用心得
  10. XGBoost结合SHAP应用:回归、二分类、多分类模型
  11. 如何设置内网端口映射外网
  12. 2021 年使用人数最多的5款主流前端框架点评
  13. 数据改版 | CnOpenData中国行政区划数据
  14. 看完《一九四二》的感受--也写给正在找工作时迷茫的你
  15. 台式计算机怎么连接蓝牙 win10,win10台式电脑蓝牙怎么开启(开启电脑蓝牙的步骤图)...
  16. 保温杯哪种材质最好_玻璃杯材质分为哪几种 玻璃杯什么材质最好
  17. 《流畅的Python第二版》读书笔记——文本和字节序列
  18. 心形线(Java语言实现) 原理与具体实现
  19. 达梦企业管理器DEM的安装部署
  20. 直接在文件夹打开cmd

热门文章

  1. 字符串劈分(含中文)
  2. 0930_C/C++笔试题_12:16道c语言面试【6/7】
  3. Android静默安装
  4. Windows XP sp3上可以安装SQL Server 2008企业版?
  5. 使用Python教你秒搭本地服务器
  6. ViewPager嵌套viewpager有什么冲突问题
  7. Luogu1501[国家集训队] Tree II
  8. element-ui分页器的使用
  9. vue学习笔记-2-模板语法中得指令
  10. 从优秀到卓越 pdf_演讲口才培训:演讲能力是卓越领导者需要具备的能力