c 程序堆与栈,全局变量地址的研究.

c 程序堆与栈,全局变量地址的研究.

先来一段简单的测试程序.

#include <stdio.h>
#include <stdlib.h>
int gi,gj,gk; //全局变量,先声明的变量地址要大一点.
int main()
{
	int i=1;
	int j=2;
	int k=3;
	char *p=(char *)malloc(10);
	printf("global addr gi:%p,gj:%p, gk:%p\n",&gi,&gj,&gk);
	printf("malloc p:%p\n",p);
	printf("addr i:%p,j:%p, k:%p\n",&i,&j,&k);
	return 0;
}

这是ubuntu gcc7.5.0 编译的.
$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
Target: x86_64-linux-gnu
gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)
看一下运行结果

$ ./test_c 
global addr gi:0x561d3b18b010,gj:0x561d3b18b014, gk:0x561d3b18b018
malloc p:0x561d3cc61260
addr i:0x7ffd48ecbeb4,j:0x7ffd48ecbeb8, k:0x7ffd48ecbebc

用gdb 调试来看, 又有另一番地址景象
  global addr gi:0x555555755010,gj:0x555555755014, gk:0x555555755018
(gdb) next
  malloc p:0x555555756260
(gdb) next
  addr i:0x7fffffffdcd4,j:0x7fffffffdcd8, k:0x7fffffffdcdc

嗯, 看起来有点不爽. 是的,gdb调试和直接运行地址有些不同.
用gdb 调试看, 栈地址看顺眼了,应该从0x7fffffffffff 向下分配的.
但全局变量和堆地址它们的起始地址怎么还是看不透呢? 看起来像是从0x5555xxxxxxxx开始?
顺便看一下全局变量的地址, 用nm 查看

0000000000201010 D gi
0000000000201014 D gj
0000000000201018 D gk
看到gcc 编译地址与gdb调试地址是不一样的,有一个偏移, 与直接运行地址也不一样,有另一个偏移
加的偏移确实有点不伦不类,虽然我知道尽管运行是不会有问题的.

到centos7 下试一试吧. 看看是如何结果.
# gcc -v
gcc version 8.3.1 20190311 (Red Hat 8.3.1-3) (GCC)

 ./test_c 
 addr i:0x7ffc0a6a3d14,j:0x7ffc0a6a3d10, k:0x7ffc0a6a3d0c
 global addr gi:0x60103c,gj:0x601040, gk:0x601044
 malloc p:0x1477610


(gdb) next 
  addr i:0x7fffffffd8f4,j:0x7fffffffd8f0, k:0x7fffffffd8ec
(gdb) next 
  global addr gi:0x60103c,gj:0x601040, gk:0x601044
(gdb) next
  malloc p:0x60a610

这个看着还比较顺眼. 栈从0x7fffffffffff 开始递减.
堆从0(0地址开始处已经被代码,数据占据)开始,向上递增.
查一下全局变量gcc 给的地址
000000000060103c D gi
0000000000601040 D gj
0000000000601044 D gk
gcc 编译地址, gdb调试地址及直接运行地址是一致的.

抛掉那个不爽快的ubuntu7.5 gcc 编译器. 我们还是可以得出结论.
堆是从低向高递长的, 起始点就是全局数据的结尾.
栈是从高向低递长的,其高点就是0x7fffffffffff.
建立这样的一个概念很重要!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值