一起talk C栗子吧(第一百三十一回:C语言实例--C程序内存布局三)

本文主要是介绍一起talk C栗子吧(第一百三十一回:C语言实例--C程序内存布局三),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


各位看官们,大家好,上一回中咱们说的是C程序内存布局的例子,这一回咱们继续说该例子。闲话休提,言归正转。让我们一起talk C栗子吧!

看官们,关于C程序内存布局的例子,我们在前面的两个章回都介绍过了,这一回我们将对前面章回中的内容进行总结和提示。

内存布局总结

C程序的内存布局主要有四个分区:代码区,数据区(data和bss),堆区和栈区。可以使用readelf -S filename查看各个分区的内存地址。这四个分区在内存中从低地址空间开始依次向高地址延伸。我们再次使用前面章回中的图直观地展示给大家,并且对这些分区做一个全面的总结。

这里写图片描述

  • 代码区:主要存放程序的代码,位于内存的低地址空间中。
  • 数据区:它的地址空间位于代码区上面,主要存放程序中的变量,不过函数中的局部非静态变量不在该区域中,而是在栈区中。关于变量的类型不同,存放的区域也不同,更加详细的划分,请参考下面data和bss相关的信息。
  • data:主要存放程序中初始化的全局变量和局部静态变量。其中全局变量不用区分静态和非静态,只要是全局变量都在该区域中。
  • bss:主要存放程序中未初始化的全局变量和局部静态变量。其中全局变量不用区分静态和非静态,只要是全局变量都在该区域中。
  • 堆区:位于数据区上面,堆区的大小不固定,它主要存放程序中动态分配的内存。该区域的分配和回收由程序员自己控制,因此也容易出问题。
  • 栈区:位于堆区上面,栈区的大小也不固定,它主要存放函数中的局部非静态变量和函数调用相关的信息。该区域由系统进行管理,程序员不能控制。

总结完分区的内容后,我们结合前面章回中的例子,总结一下例子中各个变量在内存中的分布信息,大家从中可以看到,例子中各个变量在内存中的分布和我们上面总结的内容完全一致。

内存分区                分区起始地址       分区中存放的变量和代码
栈区:                  0xbfde3000   存放函数和局部变量:la1,la2,i
堆区:                  0x0964d000   存放动态分配的内存空间:p所指向的空间.
数据区中的bss区:        0x0804a038   存放程序中未初始化的全局变量和局部静态变量:ga1,static_la1
数据区中data区:         0x0804a028   存放程序中初始化的全局变量和局部静态变量:ga2,static_la2
代码区:                0x080483e0    存放程序的代码

内存布局细节

除了总结外,我们还有一些小的细节需要共享给大家。希望引起大家的注意:

  • 1.在内存布局图中堆区和栈区的分界处各有一条绿线。它表示堆区和栈区的大小是在变化的,它们不像代码区和数据区一样拥有固定的大小。
  • 2.堆区的内存空间是从低地址向高地址延伸,而栈区的内存空间是从高地址向低地址延伸。尽管它们都是大小可以变化的分区,但是在分区变化的方向上正好相反。
  • 3.程序中代码区和数据区的地址空间是固定的,不会随着程序运行而发生变化。但是程序中堆区和栈区的地址空间是动态变化的。已经有细心的看官发现了,我们在上一回中的例子,运行过两次,位于数据区中的变量地址在两次运行结果中完全一致,但是位于堆区和栈区中的变量地址在两次运行结果中不相同。这便是最好的证明。

内存布局之外

看官们,俗话说的好,当局者迷,旁观者清。在大家仔细观察内存中的各个分区时,让我们跳出这些分区之外,从整个内存的角度来做一些说明,希望能把大家就“迷局”中拉出来 。

  • 1.我们在这些章回中说的地址都是指虚拟内存地址,这点在一百二十九回介绍过。
  • 2.内存的布局除了我们介绍的这四个分区外,还有其它的分区。只是这四个分区与代码的关系更加密切一些。
  • 3.使用readelf工具可以查看可执行文件中的分区信息,不过这里只使用了该命令的S选项,其它的选项没有介绍,大家可以自己摸索一下。
  • 4.通过/proc虚拟目录中的文件来查看内存相关的信息,主要有cmdline,maps,status。readelf查看的是程序已经固定的静态信息,像堆,栈这些动态信息,就需要查看proc目录中的文件了,该目录中的文件提供了程序运行时的实时信息。

各位看官,关于C程序内存布局的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解 。


这篇关于一起talk C栗子吧(第一百三十一回:C语言实例--C程序内存布局三)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/800197

相关文章

从基础到高级详解Go语言中错误处理的实践指南

《从基础到高级详解Go语言中错误处理的实践指南》Go语言采用了一种独特而明确的错误处理哲学,与其他主流编程语言形成鲜明对比,本文将为大家详细介绍Go语言中错误处理详细方法,希望对大家有所帮助... 目录1 Go 错误处理哲学与核心机制1.1 错误接口设计1.2 错误与异常的区别2 错误创建与检查2.1 基础

java程序远程debug原理与配置全过程

《java程序远程debug原理与配置全过程》文章介绍了Java远程调试的JPDA体系,包含JVMTI监控JVM、JDWP传输调试命令、JDI提供调试接口,通过-Xdebug、-Xrunjdwp参数配... 目录背景组成模块间联系IBM对三个模块的详细介绍编程使用总结背景日常工作中,每个程序员都会遇到bu

Python内存管理机制之垃圾回收与引用计数操作全过程

《Python内存管理机制之垃圾回收与引用计数操作全过程》SQLAlchemy是Python中最流行的ORM(对象关系映射)框架之一,它提供了高效且灵活的数据库操作方式,本文将介绍如何使用SQLAlc... 目录安装核心概念连接数据库定义数据模型创建数据库表基本CRUD操作创建数据读取数据更新数据删除数据查

Go语言中json操作的实现

《Go语言中json操作的实现》本文主要介绍了Go语言中的json操作的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录 一、jsOChina编程N 与 Go 类型对应关系️ 二、基本操作:编码与解码 三、结构体标签(Struc

uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)

《uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)》在uni-app开发中,文件上传和图片处理是很常见的需求,但也经常会遇到各种问题,下面:本文主要介绍uni-app小程序项目中实... 目录方式一:使用<canvas>实现图片压缩(推荐,兼容性好)示例代码(小程序平台):方式二:使用uni

PyQt6 键盘事件处理的实现及实例代码

《PyQt6键盘事件处理的实现及实例代码》本文主要介绍了PyQt6键盘事件处理的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起... 目录一、键盘事件处理详解1、核心事件处理器2、事件对象 QKeyEvent3、修饰键处理(1)、修饰键类

python语言中的常用容器(集合)示例详解

《python语言中的常用容器(集合)示例详解》Python集合是一种无序且不重复的数据容器,它可以存储任意类型的对象,包括数字、字符串、元组等,下面:本文主要介绍python语言中常用容器(集合... 目录1.核心内置容器1. 列表2. 元组3. 集合4. 冻结集合5. 字典2.collections模块

基于Go语言开发一个 IP 归属地查询接口工具

《基于Go语言开发一个IP归属地查询接口工具》在日常开发中,IP地址归属地查询是一个常见需求,本文将带大家使用Go语言快速开发一个IP归属地查询接口服务,有需要的小伙伴可以了解下... 目录功能目标技术栈项目结构核心代码(main.go)使用方法扩展功能总结在日常开发中,IP 地址归属地查询是一个常见需求:

k8s容器放开锁内存限制问题

《k8s容器放开锁内存限制问题》nccl-test容器运行mpirun时因NCCL_BUFFSIZE过大导致OOM,需通过修改docker服务配置文件,将LimitMEMLOCK设为infinity并... 目录问题问题确认放开容器max locked memory限制总结参考:https://Access

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF