C++ 程序的内存分配

C++ 程序的内存分配

  • C++ 程序的内存分配
    • 数据区
    • 程序代码区
    • 参考

C++ 程序的内存分配

一个 C++ 编译的程序占用内存分为以下几个部分(从高地址到低地址):

  1. 内核空间:由操作系统创建并控制,用户代码不能读写。
  2. 栈:由编译器自动分配与释放,存放为运行时函数分配的局部变量、函数参数、返回数据、返回地址等。其操作类似于数据结构中的栈。
  3. 堆:一般由程序员自动分配,如果程序员没有释放,程序结束时可能由操作系统回收。其分配类似于链表。
  4. 数据区:存放全局变量、静态数据、常量。程序结束后由系统释放。可以细分为全局/静态存储区和文字常量区。而全局区分为已初始化全局区(data)和未初始化全局区(bss)。
  5. 程序代码区:存放程序的二进制代码。

在这里插入图片描述

实例:

在这里插入图片描述

由编译器在编译时自动分配和释放。

进栈出栈有相应的计算机指令支持,而且分配专门的寄存器存储栈的地址,效率高。

栈区是从高地址位向低地址位增长的,是一块连续的内存区域,最大容量是由系统预先定义好的,申请的栈空间超过这个界限时会提示溢出,用户能从栈中获取的空间较小。

栈能申请的最大分配大小是多少?为什么?
通过命令 ulimit -s 查看linux的默认栈空间大小,默认情况下为8192 KB,即8MB。也可以临时修改栈空间的默认大小,ulimit -s 102400,即修改为100MB。
限制栈的大小主要是因为栈的地址空间必须连续,如果任其任意成长,会内存溢出(Stack Overflow)。一般遇到这个问题有两种常见情况:

  1. 定义了较大的局部变量,导致超出了栈的最大内存。
  2. 递归调用的层次较深,由于在函数递归调用中,局部变量都要到递归结束后才能释放,所以很容易导致内存溢出。解决方法是在调用的过程中使用动态内存分配。

当一个函数被调用时,该函数的返回类型和一些调用的信息被存放到栈中。然后这个被调用的函数再为他的自动变量和临时变量在栈上分配空间。每调用一个函数一个新的栈就会被使用。

堆用于动态分配内存,位于BSS和栈中间的地址区域。由程序员申请分配和释放。

堆是从低地址位向高地址位增长,采用链式存储结构。频繁的malloc/free造成内存空间的不连续,产生碎片。当申请堆空间时库函数是按照一定的算法搜索可用的足够大的空间。因此堆的效率比栈要低的多。

在C++中,malloc/new申请的内存都是从堆内存上分配的,用完后由free/delete区释放的。如果没有释放堆内存,则会造成内存泄漏,程序结束时由操作系统统一回收。

内存泄漏的危害:长期运行的程序出现内存泄漏,影响很大,如操作系统、后台服务等等,出现内存泄漏会导致响应越来越慢,最终卡死。

数据区

全局变量和静态变量的内存就是在该区上分配的,全局变量和静态变量的生命周期也是一样的,都是在程序启动时分配内存,在程序退出时释放内存。

全局变量一般会使用extern关键字来声明:

extern int m_nClientId;

而静态变量则是使用static关键字来声明:

static int nCount;

数据区分为2个区域:

  1. 全局/静态存储区:分为已初始化全局区(data)和未初始化全局区(bss)。
  2. 文字常量区(text):存放常量字符串,而且不允许修改。程序结束后由系统释放。

图例:

在这里插入图片描述

text段和data段在编译时已经分配了空间,而bss段并不占用可执行文件的大小,它是由链接器来获取内存的。bss段(未进行初始化的数据)的内容并不存放在磁盘上的程序文件中。其原因是内核在程序开始运行前将它们设置为0。

程序代码区

程序代码区存放函数体(类成员函数和全局区)的二进制代码。

这部分区域的大小在程序运行前就已经确定,并且内存区域属于只读。在代码段中,也有可能包含一些只读的常数变量。

参考

  1. https://www.jb51.net/article/226330.htm
  2. https://blog.csdn.net/tjcwt2011/article/details/132189598
  3. https://blog.csdn.net/daaikuaichuan/article/details/89006402
  4. https://blog.csdn.net/weixin_56054625/article/details/136047382
  5. https://blog.csdn.net/qq_72982923/article/details/132197354

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

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

相关文章

【ds】替换空格

用‘%20’替换空格 var replaceBlank (charArr)> {if (!charArr || charArr.length 0) return var len charArr.lengthlet spaceLen 0for (let i 0; i < len; i) {if (charArr[i] ) {spaceLen}}var extraLen spaceLen * 2 // -> 20% 每一个空格需要增加2个ch…

Pytest精通指南(23)钩子函数-执行顺序(pytest-ordering)

文章目录 前言应用场景插件安装参数分析装饰方法装饰类装饰模块 前言 pytest-ordering 是一个pytest插件&#xff0c;它允许用户自定义测试用例的执行顺序。 默认情况下&#xff0c;pytest会按照模块、类、函数定义的顺序以及它们的名称的字母顺序来执行测试用例。 但通过使用 …

Kafka集群搭建可视化指南

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 Kafka集群搭建可视化指南 前言准备工作硬件要求环境准备 kafka集群的部署与配置3.1 单节点部署与多节点集群搭建单节点部署&#xff1a;多节点集群搭建&#xff1a; 3.2 Broker配置与优化3.3 Topic的创…

如何30天快速掌握键盘盲打

失业后在家备考公务员&#xff0c;发现了自己不正确的打字方式&#xff0c;决定每天抽出一点时间练习打字。在抖音上看到一些高手的飞速盲打键盘后&#xff0c;觉得使用正确的指法打字是很必要的。 练习打字&#xff0c;掌握正确的键盘指法十分关键。 练习打字的第一步是找到…

RIP最短路实验(思科)

华为设备参考&#xff1a;RIP最短路实验&#xff08;华为&#xff09; 一&#xff0c;技术简介 RIP&#xff08;Routing Information Protocol&#xff0c;路由信息协议&#xff09;是一种基于距离矢量的内部网关协议&#xff0c;工作原理是每个路由器周期性地向邻居路由器发…

分享一款嵌入式开源按键框架代码工程MultiButton

一、工程简介 MultiButton 是一个小巧简单易用的事件驱动型按键驱动模块。 Github地址&#xff1a;https://github.com/0x1abin/MultiButton 这个项目非常精简&#xff0c;只有两个文件&#xff1a; &#xff08;1&#xff09;可无限扩展按键&#xff1b; &#xff08;2&#x…

sublime text的json快捷键

系统 macos 配置 sublime Text->Settings->Key Bindings 效果 可以看到&#xff0c;按&#xff1a;shiftcommandp&#xff0c;会出现快捷键窗口&#xff0c;打pretty&#xff0c;会出现Format JSON&#xff0c;最右侧显示⌘J&#xff0c;说明只需要macos的⌘和J同时按…

垃圾回收知识整理

1.为什么要有垃圾回收 提高开发效率:程序员无需显式地分配和释放内存&#xff0c;这是由Java虚拟机&#xff08;JVM&#xff09;自动处理的。这种自动内存管理大大简化了程序员的工作。 减少程序错误: 手动管理内存致各种内存管理错误&#xff08;如内存泄漏、野指针等&#xf…

linux 设备树-of_address_to_resource

实例分析-reg 属性解析(基于ranges属性) /{#address-cells <0x01>;#size-cells <0x01>;soc {compatible "simple-bus";#address-cells <0x01>;#size-cells <0x01>;ranges <0x7e000000 0x3f000000 0x1000000 0x40000000 0x40000000…

arkts子组件调用父组件的方法api10+

最近都在开发鸿蒙next的应用&#xff0c;记录下来关于子组件调用父组件的方法 以Tabs为例 首先父组件是Index&#xff0c;里面有一个子组件mainView&#xff0c;实现mainView调用了父组件changeTab的方法。 Entry Component struct Index {private tabsController: TabsContr…

idea项目启动异常:Command line is too long.

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; idea中启动项目报错&#xff1a; 解决方案 在idea 的运行配置中&#xff0c;修改enviroment下的shorten command line 为jar manifest 注&#xff1a; 有时shorten command line 可能不是默认存在的…

BAPI_BATCH_CHANGE:修改批次的特征值

文章目录 BAPI_BATCH_CHANGE&#xff1a;修改批次的特征值实现步骤定义变量获取对象/类等 获取已维护特性值新特性值更新 注意事项最终效果字段介绍 BAPI_BATCH_CHANGE&#xff1a;修改批次的特征值 现在有一个需求是要修改批次里面的某一个特征值&#xff0c;所以需要使用到B…