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.mzph.cn/news/826625.shtml

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

相关文章

mysql 日环比 统计

接到一个任务,要计算日环比的情况。 16、查询销售额日环比情况 日环比: (今日-昨日)/ 昨日 的一个比率情况。 1,建表 DROP TABLE IF EXISTS sale; create table sale(id int not null AUTO_INCREMENT,record_date da…

IDEA插件:CodeGeex

前言 CodeGeeX是由清华大学和智谱AI联合开发的多语言代码生成模型。CodeGeeX是一款AI编程助手,其功能类似于Github Copilot、Codeium、CodeWhisperer、Bito等智能编程助手。CodeGeeX支持Python、C、Java、JavaScript、Go等10多种主流编程语言。它可以帮助程…

windows驱动开发-WDM框架(一)

在前面的文章中解释过,NT5.0之后windows确定了新的架构Windows Driver Model (WDM),在Vista之后又推出了Windows Driver Framework(WDF),这两个都属于驱动程序框架,那么它们的之间的关系是怎样的? WDF是对WDM进行的封…

利用大语言模型,矢量数据库实现数据库的智能搜索

目的 数据库使用SQL 语言查询数据,数据库的记录中要有一个关键字段(通常称为主键字段,它的值在数据库列表中是唯一的),数据记录是结构化的. 如果你需要根据数据记录的内容来查询数据记录,就需要通过Select 语句在数据库…

OpenCV杂记(1):绘制OSD(cv::getTextSize, cv::putText)

1. 简述 我们使用OpenCV时,有时会在图像的某个位置绘制OSD信息,如绘制一些字符串作为指示信息。 本文将简要介绍在图像(cv::Mat)上绘制固定的字符串信息。 2. 使用的API (1)cv::getTextSize() CV_EXPORT…

vue3 删除对象中的属性,可以使用js里的delete,但需注意ts定义对象类型!

如上如,当使用delete 删除stateData中的属性时, 报错,意思为 TypeScript 错误“‘delete’ 运算符的操作数必须是可选的 什么原因呢?是因为我偷懒 缺少了ts定义类型 方法一: (不推荐) delete …

MultiHeadAttention在Tensorflow中的实现原理

前言 通过这篇文章,你可以学习到Tensorflow实现MultiHeadAttention的底层原理。 一、MultiHeadAttention的本质内涵 1.Self_Atention机制 MultiHeadAttention是Self_Atention的多头堆嵌,有必要对Self_Atention机制进行一次深入浅出的理解,这…

Linux Makefile用法

1、什么是makefile? Makefile:将不同模块放在不同的目录中,定义一系列的规则进行 “自动化编译”2、Makefile写法 vim makefile 填写样例: app:sub.c add.c mult.c div.c main.cgcc sub.c add.c mult.c div.c main.c -o app3、工作…

刷代码随想录有感(39):每层最大值

题干: 代码: /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), …

OpenCV基本图像处理操作(十一)——图像特征Sift算法

图像尺度空间 在一定的范围内,无论物体是大还是小,人眼都可以分辨出来,然而计算机要有相同的能力却很难,所以要让机器能够对物体在不同尺度下有一个统一的认知,就需要考虑图像在不同的尺度下都存在的特点。 尺度空间的…

《6G数据面架构研究》

目录 一、数据服务的定义二、6G数据服务驱动力及面临的挑战6G数据服务的业务驱动6G数据服务的技术驱动6G数据服务的网络内在驱动6G数据面面临的挑战 三、6G数据服务典型场景自动化网络运维用户体验提升通信感知数据服务 四、6G数据面架构研究数据面架构视图功能定义说明&#x…

kafka部分partition的leader=-1修复方案整理

kafka部分partition的leader-1修复方案整理 1. 背景说明2. 修复测试2.1 创建正常的topic并验证生产和消费2.2 停止kafka模拟leader-12.3 修复parition2.4 修复完成验证生产消费是否恢复 3. 疑问和思考3.1 kafka在进行数据消费时,如果有partition的leader-1&#xff…

从迷宫问题理解dfs

文章目录 迷宫问题打印路径1思路定义一个结构体要保存所走的路径,就需要使用到栈遍历所有的可能性核心代码 部分函数递归图源代码 迷宫问题返回最短路径这里的思想同上面类似。源代码 迷宫问题打印路径1 定义一个二维数组 N*M ,如 5 5 数组下所示&…

十一、Yocto集成tcpdump等网络工具

文章目录 Yocto集成tcpdump等网络工具networking layer集成 Yocto集成tcpdump等网络工具 本篇文章为基于raspberrypi 4B单板的yocto实战系列的第十一篇文章: 一、yocto 编译raspberrypi 4B并启动 二、yocto 集成ros2(基于raspberrypi 4B) 三、Yocto创建自定义的lay…

ctf.show_web14

在switch中,case 里如果没有 break,则会继续向下执行 case。 过滤了information_schema.tables、information_schema.column、空格 information_schema.tables 或 .columns 用反引号 information_schema.tables 同时查3个字段 ?query-1/**/union/**/…

ssh免秘钥登录与时钟同步

ssh免秘钥登录及数据拷贝 ssh免秘钥登录及数据拷贝环境生成秘钥拷贝公钥到到远程服务器通过ssh-copy-id命令拷贝公钥到远程服务器通过手动拷贝公钥到远程服务器 非root用户远程拷贝公钥 设置编码方式临时设置编码永久设置方法一永久设置方法二 设置时钟同步使用 ntpdate 命令使…

血糖长期不降,乏力、视力模糊?可能治疗方向有误。

糖尿病能不能治愈,中医能不能治,这是很多人讨论的话题,现在全世界任何一家西医医院都会告诉你,糖尿病没办法治,给你的建议也是终身服药,或者打胰岛素治疗,但是我告诉你,其实这都是治…

Jmeter04:关联

1 Jmeter组件:关联 概括:2个请求之间不是独立的,一个请求响应的结果是作为另一个请求提交的数据,存在数据交互 1.1 是什么? 就是一个请求的结果是另一个请求提交的数据,二者不再是独立 1.2 为什么&#x…

深入理解Java IO流:字符流

深入理解Java IO流:字符流 引言 在Java中,IO(输入/输出)操作是程序与外部世界交互的重要方式。 其中,File类是进行文件操作的基础,而字节流和字符流则是数据传输的两种主要方式。 本文将深入探讨这些概念及…

【Redis 神秘大陆】004 高可用集群

四、Redis 高可用和集群 当你发现这些内容对你有帮助时,为了支持我的工作,不妨给一个免费的⭐Star,这将是对我最大的鼓励!感谢你的陪伴与支持!一起在技术的路上共同成长吧!点击链接:GitHub | G…