c语言系统默认布局变量,C语言程序内存布局

C语言笔记之02-C语言程序内存布局

我们知道C语言的编译过程分为:预处理-编译-汇编-链接-生成可执行文件,而这个可执行文件由代码段(text)、数据段(data)、BSS段(bss)三部分组成。在执行可执行文件的时候,需要将这个可执行文件装配到内存中才能运行,这个中间涉及到一个C程序的内存的布局,主要是变量、常量和函数的存放位置,因此需要搞懂它的内存布局,才能很好理解程序的内存结构和优化。

内存映射

下图是C程序的内存模型

68742efadbd9

Linux下32位环境的用户空间内存分布

代码段(text)

代码段存放的是可执行文件的可执行指令,从图中可以看出,代码段是放在内存最低地址处,这段区域是只读区域,也是可共享的。装配时直接将该段代码直接拷贝到内存的.text区。

常量区(data)

常量段也是整个数据段的一部分,主要存储常量和字符串常量,该段也是只读区域。

全局数据区(data)

全局数据区也是数据段的一部分,主要存储全局变量、static变量,该段有两部分组成:可读写数据区和只读数据区。

未初始化数据区(bss)

bss存放未初始化的全局变量和static变量

堆段(heap)

heap是写程序中经常遇到的一个区域,这块区域是动态内存分配区,堆地址从内存低地址往高地址增长,完全由程序猿自己分配和释放,这个地方一般最容易出现内存没有释放导致程序crash。在C语言中经常使用的函数就是malloc/calloc/realloc/free.

栈段(stack)

stack是函数执行和调用中打交道最多的地方,这块区域专门存放函数的参数、局部变量,栈的地址是由高到底进行分配,与堆正好相反。一般程序中的栈空间是有限的,其只是程序的一个临时存储区,所以在函数内部申请大的内存必须要使用堆来申请,切记不能使用数组来申请大的空间。

实例

一般面试题经常会考到的地方就是关于字符串常量的指针是否相等,如这个例子中的str1、str3,str7,str8是指向同一个内存地址。

#include

#include

char *str1 = "helloworld"; //字符串helloworld放在已初始化数据区(常量区),str1放在全局数据区

char str2[] = "helloworld";//字符串helloworld和str2放在全局数据区

static char *str3 = "helloworld";//字符串helloworld放在已初始化区(常量区),str3放在全局数据区

static char str4[] = "helloworld";//字符串helloworld和str4放在全局数据区

char *str5;//str5放在全局未初始化数据区

static char *str6;//str6放在全局未初始化数据区

int a1;//全局未初始化数据区

static int a2;//全局未初始化数据区

const char *str11;//全局未初始化数据区

int main(int argc, char **argv){

static char *str7 = "helloworld";//helloworld是字符串常量放在常量区,str7放在全局数据区

char *str8 = "helloworld";//helloworld是字符串常量,str8放在栈区

char str9[] = "helloworld";//helloworld不是字符串常量,都放在栈区

char *str10 = (char *)malloc(sizeof("helloworld"));//str10放在堆区

const char *str12;//栈区

char *str13;

printf("str1 %p, str2 %p, str3 %p, str4 %p\n", str1, str2, str3, str4);

printf("str5 %p, str6 %p\n", str5, str6);

printf("a1 %p, a2 %p\n", &a1, &a2);

printf("str7 %p, str8 %p, str9 %p, str10 %p\n", str7, str8, str9, str10);

printf("str11 %p, str12 %p, str13 %p\n", str11, str12, str13);

if (str10){

free(str10);

str10 = NULL;

}

return 0;

}

这个例子中最容易混淆的地方就是char str9[] = "helloworld",数组形式定义的并不是字符串常量。

参考

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值