专栏首页magicsoarC++内存布局(1)-让new出的两个变量在堆上的地址连续

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

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

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

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所指的地方分配内存

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • windows下的C++ socket服务器(2)

    int make_server_socket(int port);//1 void handleAccept(int socket_fd);//2 int ma...

    magicsoar
  • windows下的C++ socket服务器(3)

    int make_server_socket(int port) { WSADATA inet_WsaData;//1 WSAStar...

    magicsoar
  • C++ socket网络爬虫(1)

    C++写的socket网络爬虫,代码会在最后一次讲解中提供给大家,同时我也会在写的同时不断的对代码进行完善与修改 我首先向大家讲解如何将网页中的内容,文本,图片...

    magicsoar
  • Java基础-方法

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    cwl_java
  • 面试题

    程序手艺人
  • codevs1735 方程的解数(meet in the middle)

    attack
  • BZOJ 1179: [Apio2009]Atm(tarjan+SPFA)

    Description Siruseri 城中的道路都是单向的。不同的道路由路口连接。按照法律的规定, 在每个路口都设立了一个 Siruser i 银行的 AT...

    attack
  • BZOJ2152: 聪聪可可(点分治)

    聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃、两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况...

    attack
  • C++版 - 剑指offer 面试题30:最小的K个数(topK问题) 题解

    题目: 输入n个整数,找出其中最小的k个数。例如:例如输入4 、5 、1、6、2、7、3 、8 这8 个数字,则最小的4 个数字是1 、2、3 、4

    Enjoy233
  • LeetCode 323. 无向图中连通分量的数目(并查集)

    给定编号从 0 到 n-1 的 n 个节点和一个无向边列表(每条边都是一对节点),请编写一个函数来计算无向图中连通分量的数目。

    Michael阿明

扫码关注云+社区

领取腾讯云代金券