堆的地址怎么比栈还高啊?+栈和堆的地址哪个高+64位系统,调试时显示的地址为48位+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", 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

  • 可表示的地址空间为 2 48 2^{48} 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//代码段

cam

猜你喜欢

转载自blog.csdn.net/zhoutianzi12/article/details/107592159