C程序的储存空间是如何分配?

可执行程序包括BSS段、数据段、代码段。

在类UNIX系统下可使用size命令查看可执行文件的段大小信息。如size a.out:

~/Desktop/MyC$ size a.outtext	   data	    bss	    dec	    hex	filename1672	    600	      8	   2280	    8e8	a.out

1.数据段存放已初始化的全局变量和静态变量,数据段属于静态内存分配。
2.BSS段(Block Started by Symbol)存放未初始化的全局变量和静态变量。
        BSS段的数据是可读写的,链接器从可执行文件中得到BSS段的大小,然后申请得到这块内存空间,这块内存空间紧跟在数据段的后面。由此可知BSS段并不占用可执行文件的大小。在使用BSS段之前BSS段会自动初始化为0。所以,未初始的全局变量和静态变量在程序执行之前已经是0了。BSS段属于静态内存分配。

包含数据段和BSS段的整个区段通常称为数据区。

3.代码段:用来存放程序的代码内存空间。它的大小在程序运行前就已经确定了,并且该区域只能读不能写。在代码段中,也有可能包含了一些只读的常数变量,例如字符串常量等。

        代码段和数据段在编译时已经分配了空间,而BSS段则在程序被调入内存后才分配的。因此BSS段(未进行初始化的数据)的内容并不存放在磁盘上的程序文件中。需要存放在程序文件中的只有代码段和数据段(存放已初始化的全局变量和静态变量)的内容。

        程序编译后生成的目标文件至少含有这三个段,这三个段的大致结构图如下所示:

在这里插入图片描述在这里插入图片描述

可执行程序在运行时会多出两个区域:栈区和堆区。
4.栈区:由操作系统自动分配和释放 ,存放函数的参数值,局部变量的值等。每当一个函数被调用时,该函数的返回类型和一些调用的信息也会被存放到栈中。然后这个被调用的函数再为它的自动变量和临时变量在栈上分配空间。每调用一个函数一个新的栈就会被使用。栈区是从高地址位向低地址位增长的,是一块连续的内存区域,最大容量是由系统预先定义好的,申请的栈空间超过这个界限时会提示溢出,用户能从栈中获取的空间较小。

小知识:
自动变量:什么是自动变量呢?自动变量就是指在函数内部定义使用的变量。只能在函数内部使用它。自动变量是局部变量,即它的作用区域是在定义它的函数内部。由于自动变量在定义它的函数的外部是不可见的,所以允许我们在这个函数外部或者其他的函数内部定义同名的变量。计算机在执行这个函数的时候,创建这个变量并为它分配内存,当函数执行完毕返回后,自动变量就会被销毁。为自动变量分配内存就是压栈,而函数返回时就退栈。
临时变量是指在未在程序开头部分声明的,待使用它时才声明类型的变量。常见的如函数中定义的变量,循环语句、条件语句中声明定义的变量。这些变量可与主程序中的变量同名,在其作用域里,主程序中的同名变量一般无法调用。并且这种变量有效存在时间是从变量声明开始到相应程序段(循环结构或函数体)结束。

5.堆区:用于动态分配内存,位于BSS和栈中间的地址区域。由程序员亲自用malloc()申请分配和用free()释放。堆是从低地址位向高地址位增长,采用链式存储结构。频繁的 malloc/free造成内存空间的不连续,产生碎片。当申请堆空间时库函数是按照一定的算法搜索可用的足够大的空间。因此堆的效率比栈要低的多。

最后提示一下:内存泄漏是指内存分配出去以后,你再也访问不到了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/272507.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

详细讲解Android的网络通信(HttpUrlConnection和HttpClient)

前言,Android的网络通信的方式有两种:使用Socket或者HTTP,今天这一篇我们详细讲解使用HTTP实现的网络通信,HTTP又包括两种方式编程方式: (1)HttpUrlConnection; (2&#…

常见通信协议HTTP、TCP、UDP的简单介绍

TCP HTTP UDP:都是通信协议,也就是通信时所遵守的规则,只有双方按照这个规则“说话”,对方才能理解或为之服务。TCP HTTP UDP三者的关系:TCP/IP是个协议组,可分为四个层次:网络接口层、网络层、传输层和应用层…

创建进程相关函数

fork函数 pid_t fork(void); fork函数调用成功, 返回两次 在fork函数执行完毕后 如果创建新进程成功,则出现两个进程 一个是子进程,一个是父进程 在子进程中,fork函数返回0 在父进程中,fork返回新创建子进程的进程ID…

实现Windows和Linux之间的文件共享

一、windows 向linux共享文件(这里都是以win10和ubuntu为例)首先,打开网络共享中心。如图1图1打开更改高级共享设置(图2)图 2选择启用网络发现以及启用文件和打印机共享,然后点击保存更改。接着,选择你要共享的文件夹&…

鸡啄米MFC教程笔记之七:对话框:为控件添加消息处理函数

MFC为对话框和控件等定义了诸多消息,我们对它们操作时会触发消息,这些消息最终由消息处理函数处理。比如我们点击按钮时就会产生BN_CLICKED消息,修改编辑框内容时会产生EN_CHANGE消息等。一般为了让某种操作达到效果,我们只需要实…

进程的退出方式以及僵尸进程和孤儿进程

(1)正常退出 (2)异常退出 检查wait和waitpid所返回的终止状态的宏 宏说明WIFEXITED(status)若为正常终止子进程返回的状态,则为真。对于这种情况可执行WEXITSTATUS(status),取子进程传送给exit、_exit或_…

java中的动态代理----自己手动实现

代码使用了common-io,需要其jar 1 接口 Java代码 public interface Pruduct { void selling(); } 2 书籍类 Java代码 public class Book implements Pruduct { Override public void selling() { try { Thread.sleep(1000…

Code Project精彩系列(1)

ApplicationsCrafting a C# forms Editor From scratchhttp://www.codeproject.com/csharp/SharpFormEditorDemo.asp建立一个类似C#的环境, 实现控件拖拉,属性Packet Capture and Analayzer网络封包截获http://www.codeproject.com/csharp/pacanal.aspA tool to cha…

Code Project精彩系列(2)

Windows FormsFireball Resourcer把各种资源嵌入应用程序资源Window Hiding with C#隐藏窗体, 似乎是其它运行的窗体 JProper Threading in Winforms .NETWindows Forms User Settings in C#使用VS设置设定forms, coolA Pretty Good Splash Screen in C#一个自绘可爱屏幕A curt…

python bool值要注意的一些地方

1、像(),[],{}这三个是可以通过bool(()),bool([]),bool({})转化为bool值的;且它们转化后的结果为False。但是这三个值它本身并不等于False、切记不可以与False 直接进行比较。 #!/usr/bin/python #!coding:utf-8 import sysif __name__ "__main__":falseL…

前端必备知识点—SVG

基本内容什么是SVG? 全称为Scalable Vector Graphics,是一种使用XML技术描述二维图形的语言,简单来说 - 矢量图(不失真)SVG与HTML5的关系早在HTML5之前,存在SVG技术SVG文件扩展名为".svg"在HTML5出现之前,要在HTML页面中引入SVG文件在HTML5出…

CocoaPods安装和使用及问题:Setting up CocoaPods master repo

CocoaPods是什么? 当你开发iOS应用时,会经常使用到很多第三方开源类库,比如JSONKit,AFNetWorking等等。可能某个类库又用到其他类库,所以要使用它,必须得另外下载其他类库,而其他类库又用到其他…

进程间的通信IPC(无名管道和命名管道)

进程间的通信IPC介绍 进程间通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。 IPC的方式通常有管道(包括无名管道和命名管道)、消息队列、信号量、共享存储、Socket、Streams等。其中 Socket…

那些关于浏览器的趣图和幽默段子

1、当浏览器化作一种枪,你喜欢用哪种呢?2、这神奇的反射弧,有点长…3、浏览器们成长的烦恼4、这么说来,IE浏览器扳回一分!5、如何用浏览器区分 HTML和 HTML56、都在吹牛,还是IE最务实!7、主流浏…

前端新手程序员不知道的 20个小技巧

1.作为前端开发者,使用双显示器能大幅提高开发效率。2.学编程最好的语言不是PHP,是English。3.东西交付之前偷偷测试一遍。4.问别人之前最好先自己百度,google一下,以免问出太低级的问题。5.把觉得不靠谱的需求放到最后做&#xf…

DBA十大必备工具(SQLServer)

曾经和一些DBA和数据库开发人员交流时,问他们都用过一些什么样的DB方面的工具,大部分人除了SSMS和Profile之外,基本就没有使用过其他工具了;诚然,SSMS和Profile足够强大,工作的大部分内容都能通过它们搞定&…

JS一些常用的类库

一、返回上一页(history)发觉有两种用法:1、javascript:history.back(-1);2、javascript:history.go(-1);它们俩的区别是:history.back(-1):直接返回当前页的上一页,数据全部消息,返回新页面history.go(-1)…

Linux上线程开发API概要(线程)

进程与线程 典型的UNIX/Linux进程可以看成只有一个控制线程:一个进程在同一时刻只做一件事情。有了多个控制线程后,在程序设计时可以把进程设计成在同一时刻做不止一件事,每个线程各自处理独立的任务。 进程是程序执行时的一个实例&…

Redis学习笔记1-Redis数据类型

Redis数据类型 Redis支持5种数据类型,它们描述如下: Strings - 字符串 字符串是 Redis 最基本的数据类型。Redis 字符串是二进制安全的,也就是说,一个 Redis 字符串可以包含任意类型的数据,一个字符串最大为 512M 字节…

30个非常有趣的404错误页面设计欣赏

当用户访问一个不存在的页面的时候就会出现404错误页面,这对用户来说是很不友好的。所以很多网站都会去设计一个新颖的错误页面,以吸引用户继续浏览其它的网页内容。今天这篇文章就收集了30个非常有趣的404错误页面设计欣赏,希望能带给你灵感…