堆的地址怎么比栈还高啊?
#include <stdio.h>
#include <stdlib.h>
static int a = 0;
const char* p = "wefrfg";
void main()
{
int temp;
printf("%p\n", &temp);
int* pointer = (int*)malloc(sizeof(int)*99999);
printf("%p\n", &pointer);
printf("%p\n", pointer);
printf("%p\n",&a);
/*printf("%p\n", main);
printf("%p\n", &p);*/
}
- linux下面gcc搞一下,结果是这样的
0x7ffd 8619 7fc4 : &temp
0x7ffd 8619 7fc8 : &pointer
0x7fea 88f3 b010:pointer
0x0000 0060 1054 : &a
- 这个和我们正常的理解是一样的
栈和堆的地址哪个高
- 堆向高地址扩展,
- 栈向低地址扩展的,
- 那么堆和栈的地址那个高呢?
#include <stdio.h>
#include <stdlib.h>
void main()
{
int stack_val = 0;
int* heap_ptr = new int(2);
printf("stack address = %08x\n", &stack_val);
printf("heap address = %08x\n", heap_ptr);
getchar();
}
- 以上为Windows上的程序,结果栈低于堆地址,
- windows上内存是中间向两头增长的。
- 同样的程序在linux上,结果栈高于堆地址,说明linux上的内存是两头向中间增长的。
64位系统,调试时显示的地址为48位
-
用是64位的系统,
-
调试时显示的地址为48位,
-
地址为48位是表象,出现这样结果的原因是x86_64处理器硬件限制。
-
x86_64处理器地址线只有48条,
- 硬件要求传入的地址48位到63位地址必须相同,
- 若表示为16进制,
- 则前4位为ffff或者是0000。
-
有两段合法的地址空间:
0x00000000 0000 0000-0x0000 7fff ffff ffff
0xffff8000 0000 0000-0xffff ffff ffff ffff -
可表示的地址空间为 Byte=256TB,这就是当前处理器的寻址能力
-
操作系统一般使用地段地址,只用到第一段地址空间,
-
要用到第二段地址空间,则需要内存达到寻址空间的一般128TB。
-
可知:0x7fff ffff da20完整的地址其实是0x0000 7fff ffff da20,为64位
- 地址数值只有48位是表像,实际上它是64位地址,这是当前的x86_64处理器硬件限制所致。
- 目前面世的x86_64处理器的地址线只有48条,硬件要求传入的地址的48到63位必须与47位相同。因此有两段合法的地址空间,最直观的是0 - 0x00007fff ffffffff,另一段是0xffff8000 00000000 - 0xffffffff ffffffff。
- 两段加一起一共2^48 = 256TB,这就是当前处理器的寻址能力。
- 一般我们是见不到第二段地址的,
- 因为操作系统一般用低段地址,
- 高段这部分需要你的机器至少有128T以上内存
linux每种变量的存储地址
#include <stdio.h>
#include <stdlib.h>
static int a = 0;
const char* p = "wefrfg";
void main()
{
int temp;
printf("%p\n", &temp);
int* pointer = (int*)malloc(sizeof(int)*99999);
printf("%p\n", &pointer);
printf("%p\n", pointer);
printf("%p\n",&a);
printf("%p\n", &p);
printf("%p\n", p);//
printf("%p\n", main);//
}
- gcc 64位置下跑
0x7ffda820bd24 //临时变量
0x7ffda820bd28 //临时变量
0x7fe0a9cc2010 //堆
0x601054 // 全局变量
0x601048//全局变量
0x4006b4//只读的
0x40057d//代码段