C语言内存分布
C语言内存分布
典型的C语言程序内存表示分区共有5个部分:
- 正文段 Text segment
- 已初始化数据段(数据段)Initialized data segment
- 未初始化数据段(bss)Uninitialized data segment
- 堆 Stack
- 栈 Heap
具体分布图

各个分区的作用
- 正文段
- CPU执行的机器指令部分
- 通常可共享
- 常常是只读的
- 已初始化数据段(数据段)
- 包含程序中需明确赋初始值的变量
- 保存已经初始化的全局变量
- 未初始化数据段(BSS)
- 在程序开始执行之前,内核将此段中的数据初始化为0或空指针
- 保存未初始化的全局变量(注意:即使是赋值为0也是未初始化!)
- 栈
- 存储自动变量(如函数形参)及每次函数调用所需保存的信息
- 每次函数调用时,存放其返回地址及调用者的环境信息(如某些机器寄存器的值)
- 为最近被调用的函数分配自动变量和临时变量的存储空间
- 堆
- 动态存储分配
初始化?
上面提到,对全局变量来说,如果是赋值为0仍是未初始化。下面给出实际实验结果:
示例代码1
#include <stdio.h>
int a;
int main(int argc, char const *argv[])
{
printf("hello\n");
return 0;
}
编译后查看内存分布:

示例代码2
#include <stdio.h>
int a = 0;
int main(int argc, char const *argv[])
{
printf("hello\n");
return 0;
}
编译后查看内存分布:

可以看到,各个存储区域数值没有变化。
示例代码3
#include <stdio.h>
int a = 1;
int main(int argc, char const *argv[])
{
printf("hello\n");
return 0;
}
编译后查看内存分布:

可以看到,对全局变量进行真正的初始化之后,bss少了4个字节,data段多出了4个字节。
关于static的问题
示例代码4
先看看相对上一例子,多了一个局部变量之后的内存分布。
#include <stdio.h>
int a = 1;
int main(int argc, char const *argv[])
{
int b;
printf("hello\n");
return 0;
}
编译后查看内存分布:

可以看到,内存分布是没有变化的,局部变量b会在栈上分配到内存。
示例代码5
如果把b定义成static呢?
#include <stdio.h>
int a = 1;
int main(int argc, char const *argv[])
{
static int b;
printf("hello\n");
return 0;
}
编译后查看内存分布:

可以看到,此时bss上多出了8个字节。
示例代码6
如果给b赋初始值0呢?
#include <stdio.h>
int a = 1;
int main(int argc, char const *argv[])
{
static int b = 0;
printf("hello\n");
return 0;
}
编译后查看内存分布:

可以看到,跟上一个例子相比没有变化,说明跟全局变量一样,static变量赋值为0仍是未初始化。
示例代码7
如果给b赋初始值1呢?
#include <stdio.h>
int a = 1;
int main(int argc, char const *argv[])
{
static int b = 1;
printf("hello\n");
return 0;
}
编译后查看内存分布:

可以看到,bss少了4个字节,而data多了4个字节,说明静态变量和全局变量同理,初始化之后是存在data段中的。
关于static的用处
示例代码8
#include <stdio.h>
int x = 4;
void incre() {
static int x = 1;
x *= x + 1;
printf("%d\n", x);
}
int main(int argc, char const *argv[])
{
int i;
for (i = 1; i < x; i++) {
incre();
}
return 0;
}
运行结果为:

可以看到,函数incre中x的作用域存在于其局部,但是却在每次调用函数的时候沿用之前的值!这是因为static定义的变量是静态变量,有着静态存储位置(变量存储位置固定不动,若在代码中已经初始化则存在于data段,否则存在于bss段),而不是存在于栈上,因此每次调用函数读取到的变量的值都是静态存储区的值。
static的意义
全局静态变量
- 不会被其它文件所访问和修改
- 其它文件中可以使用相同名字的变量,不会发生冲突
局部静态变量
- 可以用作计数器,每次函数调用的时候可以进行计数
静态函数
- 其它文件中可以定义相同名字的函数,不会发生冲突
- 静态函数不能被其它文件所用
- 静态函数会被分配在一个一直使用的存储器,直到程序退出,避免了调用函数时进栈出栈,提升运行速度
参考书目
- 《Unix环境高级编程》(中文第三版)
- 《C primer plus》(中文第五版)
参考博客
C语言内存分布的更多相关文章
- C语言内存分布之数据段
不管我们以后是自己写代码还是读别人的代码,都应该想想这个变量默认存储的位置.在我们以后的嵌入式开发中,技巧性的代码越来越多的时候,我们可能把某一些代码放在一段.我们可以通过修改变量或者代码默认放置的段 ...
- 程序的内存分布 - 以 Linux 为例,基于 C 语言分析
这里以 Linux 为例,用 C 语言进行演示. 内存模型 - 内存空间名称 内容 读写操作 分配时机 高地址 kernel 内核空间 命令行参数.环境变量等 不可读写 程序运行时 - stack 栈 ...
- 深入理解C语言内存管理
之前在学Java的时候对于Java虚拟机中的内存分布有一定的了解,但是最近在看一些C,发现居然自己对于C语言的内存分配了解的太少. 问题不能拖,我这就来学习一下吧,争取一次搞定. 在任何程序设计环境及 ...
- 内存模型 Memory model 内存分布及程序运行中(BSS段、数据段、代码段、堆栈
C语言中内存分布及程序运行中(BSS段.数据段.代码段.堆栈) - 秦宝艳的个人页面 - 开源中国 https://my.oschina.net/pollybl1255/blog/140323 Mem ...
- 深入理解Linux C语言内存管理
问题不能拖,我这就来学习一下吧,争取一次搞定. 在任何程序设计环境及语言中,内存管理都十分重要. 内存管理的基本概念 分析C语言内存的分布先从Linux下可执行的C程序入手.现在有一个简单的C源程序h ...
- C++类内存分布
http://www.cnblogs.com/jerry19880126/p/3616999.html#undefined 书上类继承相关章节到这里就结束了,这里不妨说下C++内存分布结构,我们来看看 ...
- C语言内存对齐详解
一.字节对齐基本概念 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这就需要各种类型 ...
- C语言内存对齐详解(2)
接上一篇:C语言内存对齐详解(1) VC对结构的存储的特殊处理确实提高CPU存储变量的速度,但是有时候也带来了一些麻烦,我们也屏蔽掉变量默认的对齐方式,自己可以设定变量的对齐方式.VC 中提供了#pr ...
- C语言内存对齐详解(3)
接上一篇:C语言内存对齐详解(2) 在minix的stdarg.h文件中,定义了如下一个宏: /* Amount of space required in an argument list for a ...
随机推荐
- 《Linux内核设计与实现》Chapter 1 读书笔记
<Linux内核设计与实现>Chapter 1 读书笔记 一.Unix的特点 Unix从Multics中产生,是一个强大.健壮和稳定的操作系统. 特点 1.很简洁 2.在Unix系统中,所 ...
- 专业实训题目需求分析(3D推箱子)
业务需求: 游戏提供主菜单让玩家进行游戏设置.帮助说明,推箱子的小人可以前后左右转动,箱子可以被上下左右的推动,要有关卡设置,障碍物设置,游戏提供背景音乐的功能,要实现3D效果. 面向的用户类型 ...
- git hub 使用心得
git中重要的概念: 工作目录(working directory):在工作目录中修改文件,修改后的文件状态是modified,新添加的文件是untracked,通过git add命令将文件保存到st ...
- vs安装体验
鉴于vs都是英文,所以安装的时间实在是太长了,经过4个小时终于装完了. 首先要下载和安装Unit Test Generator.步骤为:tools->Extensions and Updates ...
- [转帖]"微信支付"勒索病毒制造者被锁定 传播、危害和疫情终极解密 --- 可以学习下一年火绒团队的分析原理的精神.
"微信支付"勒索病毒制造者被锁定 传播.危害和疫情终极解密 https://www.cnbeta.com/articles/tech/794851.htm 12月1日,首个要求&q ...
- CentOS下 NFS的简单使用以及windows 关在linux的NFS存储方法
1. 全部安装的情况下NFS已经安装到服务器上面了,如果没有安装的话 需要使用如下命令进行安装 yum -y install nfs-utils rpcbind 2. 创建需要使用的NFS目录 mkd ...
- NABCD模型
下面是我对我们团队实现的程序的最终期待. 1.N(Need) 这里做了用户需求,所面向的用户虽然是所有英语学习群体,但是主要用户还是那群英文小说阅读者,即希望通过英文小说的阅读来提升单词量的人群. 1 ...
- 51Nod 1175 区间中第K大的数 (可持久化线段树+离散)
1175 区间中第K大的数 基准时间限制:1 秒 空间限制:131072 KB 分值: 160 难度:6级算法题 一个长度为N的整数序列,编号0 - N - 1.进行Q次查询,查询编号i至j的所有 ...
- hdu 5274 Dylans loves tree (树链剖分 + 线段树 异或)
Dylans loves tree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
- MySQL的IFNULL解决判空问题
问题:mybatis返回的null类型数据消失,导致前端展示出错 思路:如果查询出的结果是空值,应当转换成空字符串.当然在前端也能进行判断,但要求后台实现这个功能. 解决方案: 使用如下方法查询: S ...