C语言程序的存储区域-阿里云开发者社区

开发者社区> rollenholt> 正文

C语言程序的存储区域

简介:
+关注继续查看

由C语言代码(文本文件)形成可执行程序(二进制文件),需要经过编译-汇编-连接三个阶段。编译过程把C语言文本文件生成汇编程序,汇编过程把汇编程序形成二进制机器代码,连接过程则将各个源文件生成的二进制机器代码文件组合成一个文件。

  C语言编写的程序经过编译-连接后,将形成一个统一文件,它由几个部分组成。在程序运行时又会产生其他几个部分,各个部分代表了不同的存储区域:

  1.代码段(Code或Text)

    代码段由程序中执行的机器代码组成。在C语言中,程序语句进行编译后,形成机器代码。在执行程序的过程中,CPU的程序计数器指向代码段的每一条机器代码,并由处理器依次运行。

  2.只读数据段(RO data)

    只读数据段是程序使用的一些不会被更改的数据,使用这些数据的方式类似查表式的操作,由于这些变量不需要更改,因此只需要放置在只读存储器中即可。

  3.已初始化读写数据段(RW data)

    已初始化数据是在程序中声明,并且具有初值的变量,这些变量需要占用存储器的空间,在程序执行时它们需要位于可读写的内存区域内,并具有初值,以供程序运行时读写。

  4.未初始化数据段(BSS)

    未初始化数据是在程序中声明,但是没有初始化的变量,这些变量在程序运行之前不需要占用存储器的空间。

  5.堆(heap)

    堆内存只在程序运行时出现,一般由程序员分配和释放。在具有操作系统的情况下,如果程序没有释放,操作系统可能在程序(例如一个进程)结束后回收内存。

  6.栈(stack)

    栈内存只在程序运行时出现,在函数内部使用的变量、函数的参数以及返回值将使用栈空间,栈空间由编译器自动分配和释放。

看一个例子:

int a = 0; //全局初始化区。        data段
 static int b=20; //全局初始化区。  data段
 char *p1; //全局未初始化区         bss段
 const int A = 10; //             rodata段
 void main(void
 {
 int b; //栈
 char s[] = "abc"; //栈
 char *p2; //栈
 static int c = 0; //全局(静态)初始化区 .data段
 char *p3 = "123456"; //123456\0在常量区,p3 在栈上。
 p1 = (char*) malloc(10);//分配得来的10和20个字节的区域就在堆区
 p2 = (char*) malloc(20);
 strcpy(p1, "123456"); //123456\0 在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方
 }

  代码段、只读数据段、读写数据段、未初始化数据段属于静态区域,而堆和栈属于动态区域。代码段、只读数据段和读写数据段将在链接之后产生,未初始化数据段将在程序初始化的时候开辟,而堆和栈将在程序的运行中分配和释放。C语言程序分为映像和运行时两种状态。在编译-连接后形成的映像中,将只包含代码段(Text)、只读数据段(RO Data)和读写数据段(RW Data)。在程序运行之前,将动态生成未初始化数据段(BSS),在程序的运行时还将动态形成堆(Heap)区域和栈(Stack)区域。一般来说,在静态的映像文件中,各个部分称之为节(Section),而在运行时的各个部分称之为段(Segment)。如果不详细区分,可以统称为段。

在C语言的程序中,对变量的使用还有以下几点需要注意:

    1.函数体中定义的变量通常是在栈上,不需要在程序中进行管理,由编绎器处理。

    2.用malloc,calloc,realloc等分配内存的函数所分配的内存空间在堆上,程序必须保证在使用free释放,否则会发生内存泄漏。

    3.所有函数体外定义的是全局变量,加了static后的变量不管是在函数内部或外部都放在全局区。

    4.使用const定义的变量将放于程序的只读数据区。

栈空间主要用于以下3数据的存储:

    1.函数内部的动态变量

    2.函数的参数

    3.函数的返回值

  栈空间是动态开辟与回收的。在函数调用过程中,如果函数调用的层次比较多,所需要的栈空间也逐渐加大,对于参数的传递和返回值,如果使用较大的结构体,在使用的栈空间也会比较大。

 转自:http://www.cnblogs.com/lyp3314/archive/2012/05/13/2497954.html

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
《Linux C编程从入门到精通》——第 2 章 在Linux中编写C语言代码 2.1Linux中C语言程序开发流程和工具介绍
Linux是用C语言写成的。反过来,Linux又为C语言提供了很好的支持,C语言编译工具gcc、调试工具gdb属于最早开发出来的一批自由软件。因此Linux与C语言形成了完美的结合,为用户提供了一个强大的编程环境,本章将介绍在Linux中编写C语言程序的流程和具体方法。
1131 0
《C++语言基础》程序阅读——指针、const、static
返回:贺老师课程教学链接 本周再补充三个和指针有关的阅读程序,进一步掌握指针工作的原理。友情提醒:画出内存,让程序的分析,在理性、有序中完成。如果有时间的变化,博客中加个自己画的图。可以在上机时通过单步执行,进一步和你在人脑中运行程序的过程进行对照。(1) 阅读程序,写出程序的运行结果并理解 #include <iostream> using namespace std;
780 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
4444 0
c语言中函数(linux命令查看依赖类库),数组(内存存储是连续的内存空间),Linux下查看&a,&a[0],a之间的值,可变数组
1、查看一个c函数依赖的类的方式: gcc t.c -o app 使用ldd app命令查看依赖的类,截图如下: 2、库函数包括:      a、C标准库函数,(c89/c99标准定义的函数接口,由操作系统厂商去实现。)      b、第三方厂商库函数,      c:自定义库函数 3、一个简单的函数的例子: 4、linux中查看上一个程序的放回值得方式是:echo
1205 0
指针,c语言关键字,作用域,生命周期,内存数据存储
 作用域:变量可被访问的有效范围。 生命周期:变量存储空间的有效生存时间。 extern int c;   通过关键字extern来告诉程序int c;是别的程序中定义的。 extern int fun(void); 表示这个方式是在其它的文件中定义的。 全局变量在程序的任何地方都可以被调用到,生命周期是从程序启动到程序
1041 0
《C++语言基础》程序阅读——异常处理和命名空间
返回:贺老师课程教学链接 阅读下面的程序,写出输出结果 (1) #include <iostream > using namespace std; int a[10]= {1,2, 3, 4, 5, 6, 7, 8, 9, 10}; int fun( int i); int main() { int i ,s=0; for( i=0; i
818 0
【OpenCV学习】子区域处理
作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/ #pragma comment( lib, "cxcore.lib" ) #pragma comment( lib, "cv.
558 0
《C++语言基础》程序阅读——构造函数和析构函数
返回:贺老师课程教学链接 请写出下面程序的运行结果,再和计算机运行的结果对照。无论对错,再想一想。 #include <iostream> using namespace std; class A { int a , b ; public : A( ) { a=b=0; cout <<"a="<<a
863 0
+关注
406
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载