C++ 程序的内存分配

news2024/11/15 23:26:37

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.coloradmin.cn/o/1611406.html

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

相关文章

政安晨:【深度学习神经网络基础】(十二)—— 深度学习概要

目录 概述 深度学习的概况 深度学习的组成部分 部分标记的数据 修正线性单元 卷积神经网络 神经元Dropout GPU训练 政安晨的个人主页:政安晨 欢迎 👍点赞✍评论⭐收藏 收录专栏: 政安晨的机器学习笔记 希望政安晨的博客能够对您有所裨益&#xf…

在Java中使用XxlCrawler时防止被反爬的几种方式

目录 前言 一、常见的反爬措施 1、User-Agent识别 2、Referer识别 3、频率限制 4、IP限制 二、XxlCrawer的应对之道 1、User-Agent应对 2、频率限制 3、IP限制 三、XxlCrawler执行解析 1、XxlCrawler对象 2、启动对象 3、信息爬取线程 总结 前言 众所周知&#x…

Parade Series - CoreAudio Loopback

Scenario 鉴于业务场景需要, 经过技术路径探索, 发现 comtypes 兼容性过于混乱,故而考虑整合一个 CoreAudio 的轮子dll来解决实际问题!std::StringStream ⇒ std::ios::binary ⇒ std::ofstream Loopback.dll #ifndef _DLL_C…

第63天:服务攻防-框架安全CVE 复现DjangoFlaskNode.JSJQuery

目录 思维导图 案例一:JavaScript-开发框架安全-Jquery&Node node.js目录穿越 CVE-2021-21315命令执行 Jquery CVE-2018-9207 案例二:Python-开发框架安全-Django&Flask django cve_2019_14234 CVE-2021-35042 flask ssti 思维导图 案…

LeetCode刷题实战4:寻找两个正序数组的中位数

题目内容 给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。 算法的时间复杂度应该为 O(log (mn)) 。 示例 1: 输入:nums1 [1,3], nums2 [2] 输出:2.0…

Three.js--》探秘虚拟现实VR展厅的视觉盛宴

今天简单实现一个three.js的小Demo,加强自己对three知识的掌握与学习,只有在项目中才能灵活将所学知识运用起来,话不多说直接开始。 目录 项目搭建 初始化three代码 camera-controls控制器使用 添加画框 画框处理事件 添加机器人模型 …

一文学会 ts 构建工具 —— tsup

文章目录 能打包什么?安装用法自定义配置文件条件配置在 package.json 中配置多入口打包生成类型声明文件sourcemap生成格式自定义输出文件代码分割产物目标环境支持 es5编译的环境变量对开发命令行工具友好监听模式 watch提供成功构建的钩子 onSuccess压缩产物 min…

LLMs之Llama3:Llama 3的简介、安装和使用方法、案例应用之详细攻略

LLMs之Llama3:Llama 3的简介、安装和使用方法、案例应用之详细攻略 导读:2024年4月18日,Meta 重磅推出了Meta Llama 3,本文章主要介绍了Meta推出的新的开源大语言模型Meta Llama 3。模型架构 Llama 3 是一种自回归语言模型&#x…

gdb 调试常用命令

运行命令 run简写r 运行程序,当遇到断点后,程序会在断点处停止运行continue简写c 运行到下一个断点next简写n 执行下一步语句,不进入函数step简写s 执行下一步语句until运行到循环体结束until 行数运行到某一行call 函数(参数)调用函数finis…

Windows10安装配置nodejs环境

一、下载 下载地址:https://nodejs.cn/download/ ​ 二、安装 1、找到node-v16.17.0-x64.msi安装包, 根据默认提示安装, 过程中间的弹窗不勾选 2、安装完成后, 打开powershell(管理员身份) ​ 3、命令行输入 node -v 和 npm -v 如下图所示则nodejs安装成功 ​ 三…

人大金仓参与编写《通信行业信息技术应用创新发展白皮书(2024年)》正式发布...

近日,由中国信息通信研究院技术与标准研究所主办的通信行业信创发展分论坛在京成功举办,人大金仓受邀分享行业信创实践经验及成果。论坛上正式发布了人大金仓参与编写的《通信行业信息技术应用创新发展白皮书(2024年)》。 本次论坛…

pycharm创建的项目

pycharm生成django templates删出 settings.py

解锁ApplicationContext vs BeanFactory: 谁更具选择性?

目录 一、聚焦源码回顾 (一)源码分析和理解 (二)简短的回顾对比建议 二、ApplicationContext vs BeanFactory特性对比 (一)主要特性总结 (二)直接建议 三、案例简单说明 &am…

21.组件组成

组件组成 组件最大的优势就是可复用性 当使用构建步骤时&#xff0c;我们一般会将 Vue 组件定义在一个单独的 .vue 文件中&#xff0c;这被叫做单文件组件(简称 SFC) 组件组成结构 <template><div>承载标签</div> </template> <script> expor…

矽塔SA8321 单通道 2.7-12.0V 持续电流 3.0A H 桥驱动芯片

描述 SA8321是为消费类产品&#xff0c;玩具和其他低压或者电池供电的运动控制类应用提供了一个集成的电机驱动器解决方案。此器件能够驱动一个直流无刷电机&#xff0c;由一个内部电荷泵生成所需的栅极驱动电压电路和4个功率 NMOS组成H桥驱动&#xff0c;集成了电机正转/反…

【ThinkPHP框架教程·Part-01】ThinkPHP6.x框架安装教程

文章目录 一、框架介绍1、框架简介和版本选择2、主要新特性 二、安装步骤1、下载并运行Composer-Setup.exe2、安装TP前切换镜像3、安装稳定版4、测试运行 一、框架介绍 1、框架简介和版本选择 Thinkphp是一种基于php的开源web应用程序开发框架ThinkPHP框架&#xff0c;是免费开…

封装个js分页插件

// 分页插件类 class PaginationPlugin {constructor(fetchDataURL, options {}) {this.fetchDataURL fetchDataURL;this.options {containerId: options.containerId || paginationContainer,dataSizeAttr: options.dataSizeAttr || toatalsize, // 修改为实际API返回的数据…

easyx库的学习(文字绘制)

前言 昨天刚刚写完了基本图形的制作&#xff0c;今天直接可以来看看&#xff0c;在easyx中使用文字 直接看代码吧 文字绘制 void drawTest() {printf("hello,EasyX");//指的是在控制台打印//设置字体大小&#xff0c;样式settextstyle(30, 0, "微软雅黑&quo…

二维码门楼牌管理应用平台建设:核实与审核的关键作用

文章目录 前言一、二维码门楼牌管理应用平台的建设背景二、核实与审核在二维码门楼牌管理中的应用三、核实与审核的重要性四、优化建议 前言 随着信息技术的快速发展&#xff0c;二维码门楼牌管理应用平台在社区管理中发挥着越来越重要的作用。本文将深入探讨该平台建设过程中…

数据结构––kmp算法(串)

kmp算法作为串的一个重要内容&#xff0c;必然有一定的难度&#xff0c;而在看到各类教辅书里的概念与解释后&#xff0c;其晦涩难懂的内容直接劝退一部分人&#xff0c;现在&#xff0c;让我们来看看吧 KMP解决的问题类型 KMP算法的作用就是在一个已知的字符串中查找子串的位…