zoukankan      html  css  js  c++  java
  • C程序内存管理

    熟悉Java语言的肯定知道,Java中内存管理是由虚拟机帮助我们完成的,在C/C++中可不是这样,程序员需要自己去分配和回收内存空间。本文记录了C程序可执行文件的存储结构、在内存中的存储结构等方面的内容。以下C程序所使用的编译器版本是GCC 4.4.7。

    从一个C程序说起

    文件的结构

    对于以下这段Hello.c程序再熟悉不过了

    #include<stdio.h> 
     
    int main(void) 

            printf("Hello World "); 
            return 0; 

    下面使用gcc编译它,然后运行可执行文件,再查看可执行文件的存储结构

    C程序内存管理

    可以看出,可执行文件Hello在存储时(没有调入内存时)分为代码区(text),数据区(data)和未初始化数据区(bss)3个部分。另外3个字段中,dec表示十进制总和,hex表示十六进制总和,filename表示文件名。各段的具体说明如下:

    (1)代码段(text segment):存放CPU执行的机器指令。通常代码区是可以共享的(即另外的执行程序可以调用它)。代码区通常是只读的,以防止程序意外的修改它的指 令。常量数据在编译时在代码区分配内存。代码区的指令包括操作码和操作对象(或对象的地址引用)。如果是立即数,就直接包含在代码中;如果是局部数据,将 在运行时的栈空间中分配,然后在引用该数据的地址;如果是bss区和数据区,在代码中同样是引用该数据的地址。

    (2)全局初始化数据区/静态数据区(initialized data segment/data segment),或者简称数据段:该区域包含了在程序中明确被初始化的全局变量,已经初始化的静态变量(包括全局静态变量和局部静态变量)。需要注意的 是,被const声明的变量和字符串常量在代码段中分配内存。这和汇编语言中的数据段的概念是类似的。

    (3)未初始化数据区bss(Block Started By Symbol):存储的是未初始化的全局变量和未初始化的静态变量。bss区域的数据在程序执行前会被内核初始化为0或者空指针(NULL),这和栈中的 变量是不同的,栈中的变量(局部变量)如果没有初始化就使用,系统会随机分配一个值给它,这是不安全的。

    上述这些都是可执行文件的存储结构分析,其实运行时的内存结构和这个十分类似,只不过多了堆内存和栈内存区域,在后面会分析到。下面通过几个例子验证之。

    还是以Hello.c程序为例

    C程序内存管理

    我们在Hello.c中增加了一句代码,定义一个常量i,通过分析比较,可以发现代码段text区大小增加了4个字节(一个int类型占4个字节),其他区域不变,可知常量是分配在代码段的。

    在上述的基础上,在添加一句,定义一个全局变量a,并给它赋值为2,观察各区域变化

    C程序内存管理

    通过比较发现,只有数据段的大小增加了4个字节,也证明了明确被初始化的全局变量是被分配在数据区的。静态变量也是一样,可自行证之。

    在上述的基础上,我们在定义一个全局变量b,但是这一个不要赋值,观察各区域变化

    C程序内存管理

    可以发现,这一次只有bss区域增加4个字节,也证明了未初始化的全局变量是分配在bss区域的。未初始化的静态变量同理,可自行证之。

    C++ 隐式类类型转化 Implicit Class-Type Conversions http://www.linuxidc.com/Linux/2013-01/78071.htm

    C语言变长数组之剖析 http://www.linuxidc.com/Linux/2013-07/86997.htm

    C语言需要注意的问题 http://www.linuxidc.com/Linux/2013-05/84301.htm

    C语言位域的使用及其注意点 http://www.linuxidc.com/Linux/2013-07/87027.htm

    C语言中简单的for循环和浮点型变量 http://www.linuxidc.com/Linux/2013-08/88514.htm

    更多详情见请继续阅读下一页的精彩内容http://www.linuxidc.com/Linux/2015-01/111157p2.htm

  • 相关阅读:
    20款时尚的 WordPress 博客主题【免费下载】
    垂涎欲滴!30个美味的食品类移动应用程序【上篇】
    Skippr – 轻量、快速的 jQuery 幻灯片插件
    Boba.js – 用于 Google 统计分析 JavaScript 库
    长期这么做的后果就是人民劳苦而得不到该有的回报,怎么能不垮
    左值与右值的根本区别在于能否获取内存地址,而能否赋值不是区分的依据
    百度后端C++电话一面
    Web 开发和数据科学家仍是 Python 开发的两大主力
    Consul架构
    去除两端逗号-JS
  • 原文地址:https://www.cnblogs.com/xuyinghui/p/4878975.html
Copyright © 2011-2022 走看看