估计会有很多初学者跟我有一样的疑惑,这些编写好的代码是放在磁盘中,但是运行将会被copy至内存中去运行。但他们在内存中是怎么分布呢。在 “linux下c编程圣经”(apue)UNIX环境高级编程一书中阐述了这一点。在这里结合网上资料以及这本书写下自己的一点学习笔记。

在内存中程序分别存储在如下几个区域中:

一、正文区(Code or Text)

对于名字有很多,有的称为代码段,代码区等等。但是实质都是一样的,都是用来存放程序语句进行编译后,形成机器的代码。一般此内存区是只读的,防止程序意外修改指令。

二、初始数据段(RO/RW data segment)

通常是用来存放程序中已初始化的全局变量的一块内存区域。又分为只读和读写两种,此数据段属于静态内存分配

三、未初始化数据段(BSS = Block Started by Symbol)

未初始化读写据是在程序中声明,但是没有初始化的变量,这些变量在程序运行之前不需要占用存储器的空间.BSS段也属于静态内存分配

四、堆(heap)

堆内存只在程序运行时出现,一般由程序员手动分配和释放,一般可以使用malloc()/nalloc() & free() 函数来申请、释放。在操作系统下,如果程序员没释放,一般操作系统可以在程序结束后回收内存

五、栈(stack)

存放程序的局部变量(但不包括static声明的变量,static意味着在数据段中存放变量)。除此以外,在函数被调用时,栈用来传递参数和返回值。由于栈的最大特点后进先出,所以栈特别方便用来保存/恢复调用现场。

用图片来解释会更加通俗。左图是书上的。从图上可以看到,栈(stack)是自顶向下生长的,即由高地址向低地址;堆(heap)是自底向上生长。右图是栈的进出示意图,很明显的后进先出。

   

这里比较重要的概念主要是 栈 和 堆。在网上收集了下他们之间的 PK “数据”

栈   

栈内存从高地址向低地址分配

堆内存将从低地址向高地址分配

栈使用线性存储的方式

堆使用链表来实现

栈是连续内存分布的方式

堆是非连续内存分布方式

栈只有一个入口,就是栈指针,栈指针标识当前栈区域中已经使用与未使用的界限,程序访问栈内存的时候都只能通过栈指针及其偏移量

堆内存有多个入口,每次分配得到的指针是访问内存的入口,每个分配内存都可被单独释放

栈内存在分配的时候,不能在程序中判断其成功与否,当栈内存的使用量比较大的时候(例如使用函数进行递归运算),栈内存可能超出系统的容量,这时程序运行将发生栈溢出错误

堆内存在分配的时候,可以在程序中判断malloc()等函数的返回值是否为NULL来确定对内存是否分配成功,是否可以使用

栈内存由编译器管理,不需要程序来管理,同时,函数内部的栈内存是不能被函数的调用者使用的

堆内存需要在程序中处理它的分配与释放情况(由程序调用具体的库函数管理),可以利用灵活的程序将堆内存的指针从函数的内部传递到函数的外部,这时各个函数都可以使用别的函数分配出来的堆内存。

栈的一些特殊定义:

栈限定只能在表的一端进行插入和删除操作的线性表。允许插入和删除的一端称作“栈顶(top)”,不允许插入和删除端称作“栈底(bottom)
空栈:这里有两种说法。1.堆栈指针指向下一个将要放入数据的空位置时。
                      2.
栈顶指向栈底地址时,即栈内没有数据时为空栈。
  (
对于上面这两种定义一直没有找到权威的出处。网上两种概念都存在,我也不知道哪种才是正确的,希望有明确此概念的大神提点下。
满栈:栈指针指向的是一个有可用数据的,也就是最后一个使用的空间。
有图才有真相,没图没人理.上图咯。

上面把空栈的两种定义都画出来了,可能有一个是有误的,等我找到权威定义后更新此文,把错误的说法列成反面例子,供大家“批斗”!

C语言探秘:C代码在内存中的分布相关推荐

  1. 【C语言】浮点型数据在内存中的存储方式

    目录 一. 前言 二. 问题的引出 三. 两类浮点型数据(float.double)在内存中的存储方式 3.1 两类浮点型数据的存储模型 3.1.1 浮点型数据数值读取的通用模型 3.1.2 floa ...

  2. C语言之程序在内存中的分布以及内存越界问题

    C语言程序在内存中的分布: bss段:该段用来存放没有被初始化或者初始化为0的全局变量,以及被static修饰的未初始化的局部变量.在程序运行的整个生命周期内都存在于内存中.这个段中的变量只占用程序运 ...

  3. c语言复制粘贴源码,c语言函数memccpy()如何复制内存中的内容实例源码介绍

    c语言函数memccpy()如何复制内存中的内容实例源码介绍.引入的头文件:#include memccpy()函数定义:void * memccpy(void *dest, const void * ...

  4. C语言图形函数代码~持续更新中

    下面总结的是一些C语言图形函数代码~持续更新中 画三类圆 #include#include#include#include#includeint main(void) { initgraph(640, ...

  5. 【转】程序在内存中的分布

    前些天学习到了程序在虚拟内存中分布的一些知识点,结合在网上查阅的一些资料,整理一下知识点.本博客参考博主 hackbuteer1的<程序在内存中的分布>这篇文章. v 在现代的操作系统中, ...

  6. c语言中全局变量内存,C语言——全局变量和局部变量在内存中的区别——及编译后的内存分区【栈-堆-全局存储区-文字常量区-程序代码区】...

    目录: 一:全局变量 二:局部变量 三:C语言经过编译之后将内存分为以下几个区域 (1)栈(stack) (2)堆(heap) (3)全局(静态)存储区 (4)文字常量区 (5)程序代码区 四:区别 ...

  7. C语言——深度剖析数据在内存中的存储

    大家好!我是保护小周ღ,本期为大家带来的是深度剖析数据在内存中的存储,不知道,大家学了这么久C语言,有没有想过一个问题,我们在程序设计中的数据是怎么在计算机中存储的?我们都知道 一个整型数据 int ...

  8. C语言—深度剖析数据在内存中的存储

    深度剖析数据在内存中的存储 数据类型介绍 类型的基本归类 整形在内存中的存储 大小端介绍 整形在内存中的存储的相关练习 浮点型在内存中的存储 浮点型在内存中的存储相关介绍 数据类型介绍 内置类型(C语 ...

  9. c语言字母存储,字符串在内存中的储存——C语言进阶

    字符串在内存中的存储--C语言进阶 字符串是以ASCII字符NUL结尾的字符序列.ASCII字符NUL表示为\0.字符串通常存储在数组或者从堆上分配的内存中.不过,并非所有的字符数组都是字符串,字符数 ...

最新文章

  1. Google Desktop 果然
  2. 串口数据字节位的理解
  3. [有限元] Ansys Workbench 19.2 平面应力问题分析示例
  4. /var/log目录中Linux日志文件的功能详解
  5. pyqt5 treeview鼠标右键菜单事件_【动手实践】使用 Vue 自定义指令实现右键菜单...
  6. 题目:求1 + 2!+ 3!+ ... + 20!的和
  7. iMX8MM linux5.15.32移植
  8. c# 非阻塞算法_c# – 了解非阻塞线程同步和Thread.MemoryBarrier
  9. 如何识别图片中的文字?三种方法轻松搞定
  10. 我在腾讯看点的导师 Steven
  11. R语言完成中国裁判文书网最新爬虫
  12. 计算机审计实训遇到的问题及解决方法,计算机审计实训总结报告.doc
  13. android P adb shell dumpsys battery 使用
  14. 胡润研究院首发中国元宇宙潜力企业榜,巨杉数据库入选未来之星企业
  15. 基于HTML美中华传统文化题材网页项目的设计与实现 (纯HTML+CSS制作中国茶文化网站)...
  16. 5.交换机环路与VLAN
  17. linux操作系统 以下哪个命令,Linux认证考试基础试题及答案
  18. 【ROS wiki】ros wiki官方教程与ROS wiki页面检索
  19. 细胞生物学-5-细胞质基质与内膜系统Cytosol and Endomembrane system
  20. 百度安全《2016网站安全报告》:近七成恶意网页是博彩和色情网站

热门文章

  1. 微服务 前台调用后台的慢的原因_20年IT农民工分享SpringCloud微服务架构实战文档...
  2. arcgis报错常用解决方法
  3. 【转】Dynamics 365中开发和注册插件介绍
  4. 【转】注册Azure AD 2.0 应用程序
  5. [你必须知道的.NET] 开篇有益
  6. 分治算法求最大最小值c语言,[蓝桥杯][算法提高VIP]和最大子序列 (C语言代码)分治法...
  7. 【Python学习】 - skimage包
  8. C++中两个常用的控制语句格式的函数(width和precision函数)
  9. 【ACM算法讲堂之 - 计算几何基础】:【点积和叉积】(附一些模板)
  10. 【51NOD - 1523】 非回文(dfs)