• 一直以来,我们只是单纯的去运行执行 C 程序,并没有关心这个可执行文件里面包含着什么东西。

  • 参考UNIX 环境高级编程 7.6,记录C程序的存储空间布局。



* ### C程序由 正文段,初始化数据段,非初始化数据段,栈,堆组成
* ### 正文段,初始化数据段,非初始化数据段(bss)
```
正文段:CPU执行的机器指令部分。
```
```
初始化数据段:通常将此段称为数据段,包含了程序中需明确的赋初始值的变量。
比如说,c 程序中出现在任何函数之外的声明。
静态变量都在 初始化数据段:
static int i = 1000;
全局变量
int test = 100;
```
```
非初始化数据段: 一般我们称为 bss 段,这一名称来源于早期的汇编运算符,意思是 block started by symbol , 在程序开始执行之前,kernel 会将这个 bss 段中的数据全部初始化为0或者是空指针。
比如说:
未初始化局部变量:
static int chen;
全局变量:
ing test1[100];
```
* ### 写一段简单的代码,看一下上面的内存分布, 名字是test.c:
```c
#include

void test(void)
{
printf("This is test function\n");
} int main(void)
{
printf(" This is main function\n");
return 0;
}
```c
看一下这个代码生成可执行文件的各个内存分布:
sbc_7109_454_pdk3@aplex:~/test/c_program$ gcc test.c -o test
sbc_7109_454_pdk3@aplex:~/test/c_program$ size test
text data bss dec hex filename
1229 552 8 1789 6fd test
    然后,我们在里面加一个局部变量,全局变量:
![](http://images2017.cnblogs.com/blog/991711/201708/991711-20170817113549365-425031064.png)
![](http://images2017.cnblogs.com/blog/991711/201708/991711-20170817113911240-769225067.png)
    在看一下局部静态变量:
![](http://images2017.cnblogs.com/blog/991711/201708/991711-20170817114334756-1509640442.png)
  • 栈和堆

    在执行程序前,我们能看到的是上面的 非初始化数据段以及初始化数据段和正文段,在执行了程序后,我们还能看到栈和堆。
    栈:自动变量以及每次函数调用时所需保存的信息都存放在此段中。每次调用函数时,其返回地址以及调用者的环境信息,都存放在栈中。然后,最近被调用的函数在栈上为其自动和临时变量分配存储空间。通过以这种方式使用栈,可以递归调用C函数,递归函数每次调用自身时,就使用一个新的栈帧,因此一个函数调用实例中的变量集不会影响另一个函数调用实例中的变量。
局部变量也是存放在栈区。
    堆:动态内存分配。堆处于非初始化数据段和栈之间。
  • 代码 test.c:

    #include <stdio.h>
#include <stdlib.h>
#include <string.h> void test(void)
{
printf("This is test function\n");
} int test1 = 100;
int test2; int main(void)
{
int a;
static int b = 100;
static int c;
char *test3; test3 = (char *)malloc(sizeof(char) * 10); int *pa = &a, *pb = &b, *pc = &c, *ptest1 = &test1, *ptest2 = &test2;
printf("桟:pa = %p\n", pa); // 桟 stack
printf("堆:test3 = %p\n", test3); // 堆 heap
printf("bss: ptest2 = %p\n", ptest2); // 未初始化的数据区
printf("bss: pc = %p\n", pc); // 未初始化的数据区 bss
printf("data: ptest1 = %p\n", ptest1); // 初始化的数据区
printf("data: pb = %p\n", pb); // 初始化的数据区 free(test3); return 0;
}
![](http://images2017.cnblogs.com/blog/991711/201708/991711-20170817131823225-423244804.png)
  • 空间分配如下图所示:

C 程序的存储空间记录的更多相关文章

  1. IT第二十天 - 面向对象编程思想、抽象类、异常处理、程序操作日志记录、本周总结 ★★★

    IT第二十天 上午 面向对象编程思想 1.组装电脑的设计: (1)电脑的组成:显示器+机箱 (2)机箱的组成:电源+主板+硬盘 (3)主板所包含的部件:cpu+内存+PCI接口+usb接口 (4)PC ...

  2. linux 下Qt WebEngine 程序打包简单记录

    本次记录仅作参考. 程序说明: 程序是一个编解码器控制管理的工具,使用到的库有:Qt的WebEngine.OpenGL模块.poco库.libmicrohttpd.libcurl.libvlc.同时程 ...

  3. 在程序异常中记录堆栈信息(使用ExWatcher)

    在我们编写程序的时候可通过IDE自带的调试环境捕捉到异常(Except)错误,并能查看到相关的信息以便我们修正程序中的问题.但当软件被发布出去后,因为所部署运行的环境与我们的调试环境有很大区别,即使在 ...

  4. IIS网站部署后,程序常见错误记录

    1.网站部署步骤 开启IIS服务.打开IIS管理器.添加网站.修改程序池(4.0).部署完成. 2.常见问题记录(问题记录比较模糊,仅做参考) (1).对于web.config连接数据库的配置为win ...

  5. zigw 和 nanoWatch, libudev.so 和 XMR 挖矿程序查杀记录

    最近这两天以来,服务器一致声音很响.本来以为有同事在运行大的程序,结果后来发现持续很长时间都是这样,并没有停的样子.后来查了一下,发现有几个可疑进程导致,干掉之后,果然服务器静悄悄了. 但是,问题并没 ...

  6. 转:使用log4net完成程序异常日志记录(使用SQLite数据库记录和普通文本记录)

    http://www.cnblogs.com/kyo-yo/archive/2010/06/11/use-log4net-to-log-exception.html 在前端时间开发的时候由于需要将异常 ...

  7. 利用jdk中工具完成Java程序监控方法记录

    转载加自己整理的部分内容,转载自:http://jiajun.iteye.com/blog/810150 记录下JConsole使用方法 一.JConsole是什么    从Java 5开始 引入了 ...

  8. Log4net控制台和窗体程序无法输出记录的原因之一

    在asp.net web应用程序中,读取log4net的配置文件可以这样写: [assembly:log4net.Config.XmlConfigurator(ConfigFile="Web ...

  9. 小程序踩坑记录-上传图片及canvas裁剪图片后上传至服务器

    最近在写微信小程序的上传图片功能,趟过了一些坑记录一下. 想要满足的需求是,从手机端上传图片至服务器,为了避免图片过大影响传输效率,需要把图片裁剪至适当大小后再传输 主要思路是,通过wx.choose ...

随机推荐

  1. 【LeetCode】127. Word Ladder

    Word Ladder Given two words (start and end), and a dictionary, find the length of shortest transform ...

  2. Java虚拟机学习 - 内存调优 ( 9 )

    JVM调优主要是针对内存管理方面的调优,包括控制各个代的大小,GC策略.由于GC开始垃圾回收时会挂起应用线程,严重影响了性能,调优的目是为了尽量降低GC所导致的应用线程暂停时间. 减少Full GC次 ...

  3. Cannot refer to the non-final local variable user defined in an enclosing scope 内部类定义在方法内,方法定义的参数(形参)无法被内部类直接访问,需要用final定义

    为什么匿名内部类参数必须为final类型 1)  从程序设计语言的理论上:局部内部类(即:定义在方法中的内部类),由于本身就是在方法内部(可出现在形式参数定义处或者方法体处),因而访问方法中的局部变量 ...

  4. Android HTTP通讯

    这里有一个非常棒的http通讯的总结,我看了以后茅塞顿开. 先贴代码: 01 public class Activity1 extends Activity { 02   03     private ...

  5. WCF 的 WebGet 方式

    .NET 3.5以后,WCF中提供了WebGet的方式,允许通过url的形式进行Web 服务的访问.在以前的代码中,写过多次类似的例子,但总是忘记如何配置,现在将设置步骤记录如下: endpoint通 ...

  6. struts2 ValueStack详解,页面获取值el表达式、ognl表达式

    http://www.blogjava.net/max/archive/2007/04/28/114417.html 我想用的是el表达式! http://www.cnblogs.com/belief ...

  7. 怎么修改Elasticsearch的对外ip 默认是本地IP 127.0.0.1

    //修改C:\Program Files\elasticsearch-2.1.1\config\elasticsearch.yml: network.bind_host: 172.16.1.86 pa ...

  8. redis 只允许指定的额内网IP访问,其余的外网IP不允许访问

    为了redis的安全,现在设定如下规则.只允许指定的服务器通过内网的方式访问.其余一律不准访问 因为redis登录额时候是不需要密码的,很不安全. 所以这里添加如下iptables规则 iptable ...

  9. mac重装系统

    通过 macOS 恢复功能启动macOS 恢复功能会根据您在电脑启动时按下的组合键来安装不同版本的 macOS.在按电源按钮打开 Mac 后,立即按住以下组合键之一.然后在看到 Apple 标志或旋转 ...

  10. RhinoMock顺序调用

    MockRepository mocks = new MockRepository(); ISongBird maleBird = (ISongBird)mocks.StrictMock(typeof ...