C/C++程序的内存是如何开辟的?
💬 欢迎讨论:在阅读过程中有任何疑问,欢迎在评论区留言,我们一起交流学习!
👍 点赞、收藏与分享:如果你觉得这篇文章对你有帮助,记得点赞、收藏,并分享给更多对C语言感兴趣的朋友
文章目录
- 前言
- 1. 栈区内存(Stack Memory)
- 栈内存的特点:
- 示例:
- 2. 堆区内存(Heap Memory)
- 堆内存的特点:
- 示例:
- 3. 数据段(静态区,Static Memory)
- 数据段的特点:
- 示例:
- 4. 代码段(Text Segment)
- 代码段的特点:
- 5. 静态变量和动态分配的内存
- 6. 柔性数组(Flexible Arrays)
- 示例:
- 结论
前言
在 C/C++ 编程中,内存的分配和管理是非常关键的,因为它直接影响到程序的性能、效率和稳定性。C/C++ 提供了不同的内存分配方式,主要分为栈内存分配和堆内存分配。每种内存分配方式都有其适用的场景和优缺点。以下是对 C/C++ 程序的内存开辟的详细解析。
1. 栈区内存(Stack Memory)
栈内存是由操作系统在程序运行时自动分配和回收的。它用于存储局部变量、函数参数、函数调用信息等。栈的特点是后进先出(LIFO,Last In First Out),也就是说,当一个函数调用结束时,它的局部变量会自动从栈中释放。
栈内存的特点:
- 自动管理:栈内存的分配和回收由编译器自动进行,无需程序员干预。
- 速度快:栈的内存分配和回收效率高,因为只需修改栈指针。
- 空间有限:栈的空间大小通常受到操作系统限制,过多的栈内存分配会导致栈溢出(stack overflow)。
- 生命周期短:栈内存的变量在超出作用域时会立即销毁。
示例:
#include <stdio.h>void testFunction() {int num = 10; // num 是在栈上分配的内存printf("Value of num: %d\n", num);
} // 当 testFunction 执行完毕,num 的内存会自动释放int main() {testFunction();return 0;
}
2. 堆区内存(Heap Memory)
堆内存是程序员通过内存分配函数(如 malloc
、calloc
、realloc
)动态分配的内存,直到程序显式调用 free
函数释放它。堆内存不受栈的大小限制,程序员可以根据需要申请任意大小的内存,适用于处理动态内存需求较大的场景。
堆内存的特点:
- 手动管理:堆内存需要程序员手动管理,程序员需要显式地调用
malloc
、calloc
、realloc
等函数进行分配,使用后需要通过free
函数释放。 - 分配较慢:相比栈内存,堆内存的分配速度较慢,因为它需要操作系统进行更复杂的内存管理。
- 内存灵活:堆内存大小没有固定限制,适合存储大数据或当数据大小在运行时不可预知时。
- 生命周期长:堆内存的生命周期由程序员控制,直到显式调用
free
函数释放。
示例:
#include <stdio.h>
#include <stdlib.h>int main() {int *p = (int *)malloc(sizeof(int)); // 在堆上分配内存if (p == NULL) {printf("Memory allocation failed\n");return 1; // 如果分配失败,返回错误}*p = 20; // 使用堆上的内存printf("Value of p: %d\n", *p);free(p); // 释放堆内存return 0;
}
3. 数据段(静态区,Static Memory)
数据段是存储程序的全局变量、静态变量以及常量数据的区域。数据段中的内存是由操作系统在程序加载时分配的。与栈和堆不同,数据段中的内存不会随着函数的调用和退出而自动释放,通常在程序结束时才会被释放。
数据段的特点:
- 静态分配:数据段中的内存是在程序加载时静态分配的,程序员无法控制。
- 生命周期长:数据段中的变量的生命周期是程序的整个生命周期。
- 内存大小固定:数据段内存大小由程序的全局变量和静态变量决定,不会动态变化。
示例:
#include <stdio.h>int globalVar = 100; // 存储在数据段int main() {static int staticVar = 200; // 存储在数据段printf("Global Variable: %d\n", globalVar);printf("Static Variable: %d\n", staticVar);return 0;
}
4. 代码段(Text Segment)
代码段存储程序的二进制指令。当程序执行时,CPU 从代码段读取并执行指令。与栈、堆、数据段不同,代码段的内存是由操作系统在程序加载时分配的,程序员不能修改它。代码段通常是只读的,防止程序意外地修改自己的代码。
代码段的特点:
- 存储程序指令:代码段用于存储编译后的程序指令。
- 不可修改:代码段通常是只读的,不允许修改。
- 程序加载时分配:操作系统会在程序加载时分配代码段内存,且它在程序的生命周期内不会变化。
5. 静态变量和动态分配的内存
C 语言支持通过 static
关键字将局部变量提升到静态存储区。这使得变量在整个程序运行期间保持其值。与栈分配的局部变量不同,静态变量的内存是在数据段分配的,因此它们的生命周期跨越整个程序的执行过程。
#include <stdio.h>void testFunction() {static int count = 0; // 静态变量count++;printf("Function called %d times\n", count);
}int main() {testFunction();testFunction();testFunction(); // count 将记住调用次数return 0;
}
6. 柔性数组(Flexible Arrays)
C99 标准引入了柔性数组,它允许在结构体中定义一个没有确定大小的数组。柔性数组通常位于结构体的最后一个成员,编译器会将其视为一个不确定大小的数组。柔性数组通常与动态内存分配(如 malloc
或 calloc
)一起使用,以便分配合适大小的内存。
示例:
#include <stdio.h>
#include <stdlib.h>typedef struct {int size;int arr[]; // 柔性数组
} MyStruct;int main() {MyStruct *s = malloc(sizeof(MyStruct) + 10 * sizeof(int)); // 分配内存if (s == NULL) {perror("Memory allocation failed");return 1;}s->size = 10;for (int i = 0; i < s->size; i++) {s->arr[i] = i * 10;}for (int i = 0; i < s->size; i++) {printf("%d ", s->arr[i]);}free(s);return 0;
}
结论
C/C++ 中的内存管理方式直接影响程序的运行效率和稳定性。栈内存适合存储临时数据,生命周期由函数调用控制;堆内存适合存储大小不定的数据,需要程序员手动管理;数据段用于存储全局和静态变量;代码段用于存储程序的执行指令。合理地选择不同的内存区域,并掌握内存管理的技巧,将有助于开发高效且稳定的 C/C++ 程序。
希望通过这篇文章,你能更加清晰地理解 C/C++ 中的内存开辟,并能在实际编程中灵活应用。
相关文章:
C/C++程序的内存是如何开辟的?
💬 欢迎讨论:在阅读过程中有任何疑问,欢迎在评论区留言,我们一起交流学习! 👍 点赞、收藏与分享:如果你觉得这篇文章对你有帮助,记得点赞、收藏,并分享给更多对C语言感兴…...

日志结构化处理:PO对象toString日志转JSON工具
日志结构化处理:PO对象toString日志转JSON工具 1. 解决的问题2. 下载地址 在Java项目中,PO(Plain Old Java Object)对象遍布各个角落,且常常伴随着大量的日志记录需求。传统的做法是通过toString方法直接打印这些对象&…...

python学opencv|读取图像(六十五)使用cv2.boundingRect()函数实现图像轮廓矩形标注
【1】引言 前序学习进程中,已经使用cv2.findContours()函数cv2.drawContours()函数实现图像轮廓识别和标注,这种标注沿着图像的轮廓进行,比较细致。相关文章链接为: python学opencv|读取图像(六十四)使用…...

大疆无人机需要的kml文件如何制作kml导出(大疆KML文件)
大疆无人机需要的轨迹kml文件,是一种专门的格式,这个kml里面只有轨迹点,其它的属性信息都不需要。 BigemapPro提供了专门的大疆格式输出, 软件这里下载 www.bigemap.com 安装后,kml导入如下图: 然后选择…...

ArrayList、LinkedList、HashMap、HashTable、HashSet、TreeSet
集合族谱 在这些集合中,仅有vector和hashtable是线程安全的,其内部方法基本都有synchronized修饰。 ArrayList 底层采用Object数组实现,实现了RandomAccess接口因此支持随机访问。插入删除操作效率慢。 ArrayList需要一份连续的内存空间。 A…...

手动配置IP
手动配置IP,需要考虑四个配置项: 四个配置项 IP地址、子网掩码、默认网关、DNS服务器 IP地址:格式表现为点分十进制,如192.168.254.1 子网掩码:用于区分网络位和主机位 【子网掩码的二进制表达式一定是连续的&#…...

idea如何使用AI编程提升效率-在IntelliJ IDEA 中安装 GitHub Copilot 插件的步骤-卓伊凡
idea如何使用AI编程提升效率-在IntelliJ IDEA 中安装 GitHub Copilot 插件的步骤-卓伊凡 问题 idea编译器 安装copilot AI工具 实际操作 在 IntelliJ IDEA 中安装 GitHub Copilot 插件的步骤如下: 打开 IntelliJ IDEA: 打开你的 IntelliJ IDEA 应用…...

游戏引擎学习第101天
回顾当前情况 昨天的进度基本上完成了所有内容,但我们还没有进行调试。虽然我们在运行时做的事情大致上是对的,但还是存在一些可能或者确定的bug。正如昨天最后提到的,既然现在时间晚了,就不太适合开始调试,所以今天我…...
css块级元素和行内元素区别
在CSS中,元素可以分为两大类:块级元素(Block-level elements)和行内元素(Inline elements)。这两种元素在网页布局中起着不同的作用,主要体现在它们的显示方式、尺寸控制、以及与其他元素的交互…...

JAVA安全—Shiro反序列化DNS利用链CC利用链AES动态调试
前言 讲了FastJson反序列化的原理和利用链,今天讲一下Shiro的反序列化利用,这个也是目前比较热门的。 原生态反序列化 我们先来复习一下原生态的反序列化,之前也是讲过的,打开我们写过的serialization_demo。代码也很简单&…...
什么是信息熵
信息熵 公式 一个离散随机变量 X X X的可能取值为 X x 1 , x 2 , . . . , x n Xx_1,x_2,...,x_n Xx1,x2,...,xn,而对应的概率为 p i p ( X x i ) p_ip(Xx_i) pip(Xxi),如下 x 1 x_1 x1 x 2 x_2 x2 x 3 x_3 x3 x 4 x_4 x4… x n x_n xnp( x …...

使用API有效率地管理Dynadot域名,清除某一文件夹中域名的默认DNS设置
关于Dynadot Dynadot是通过ICANN认证的域名注册商,自2002年成立以来,服务于全球108个国家和地区的客户,为数以万计的客户提供简洁,优惠,安全的域名注册以及管理服务。 Dynadot平台操作教程索引(包括域名邮…...

2.11 sqlite3数据库【数据库的相关操作指令、函数】
练习: 将 epoll 服务器 客户端拿来用 客户端:写一个界面,里面有注册登录 服务器:处理注册和登录逻辑,注册的话将注册的账号密码写入数据库,登录的话查询数据库中是否存在账号,并验证密码是否正确…...

当 LSTM 遇上 ARIMA!!
大家好,我是小青 ARIMA 和 LSTM 是两种常用于时间序列预测的模型,各有优劣。 ARIMA 擅长捕捉线性关系,而 LSTM 擅长处理非线性和长时间依赖的关系。将ARIMA 和 LSTM 融合,可以充分发挥它们各自的优势,构建更强大的时…...

kali连接xshell
1.先保证宿主机:以太网适配器 VMware Network Adapter VMnet8 和kali(net 模式)在同一个网段 windows VMnet8开启 查看是否是自动获取ip ipv4 和ipv6一样的 查看 windows VMnet8的IPv4的地址 查看 kali 的IP地址 window ping的结果…...
图像曲率滤波
看到这么一个非常有意思的东西,记录一下 https://www.zhihu.com/question/35499791 https://zhuanlan.zhihu.com/p/22971865 GCFilter_talk.pdf_免费高速下载|百度网盘-分享无限制 https://github.com/YuanhaoGong/CurvatureFilter?tabreadme-ov-file...
TCP 和 UDP 可以绑定相同的端口吗?
前言 当一个网络接口接收到一个数据报时,IP 模块首先检查目的地址是否为自己的 IP 地址,如果是的话,数据报交付给由 IPv4 头部的协议字段指定的协议模块。 TCP 和 UDP 在内核中是两个完全独立的模块,送给 TCP/UDP 模块的报文根据…...

【Python网络爬虫】爬取网站图片实战
【Python网络爬虫】爬取网站图片实战 Scrapying Images on Website in Action By Jackson@ML *声明:本文简要介绍如何利用Python爬取网站数据图片,仅供学习交流。如涉及敏感图片或者违禁事项,请注意规避;笔者不承担相关责任。 1. 创建Python项目 1) 获取和安装最新版…...

2024年博客之星年度评选—创作影响力评审+主题文章创作评审目前排名(2024博客之星陪跑小分队助力2024博客之星创作者成长)
2024年博客之星年度评选—创作影响力评审主题文章创作评审目前排名 2024年博客之星主题文章创作评审文章得分公布!2024年博客之星创作影响力评审2024年博客之星主题文章创作评审目前排名公布! 【2024博客之星】恭喜完成✅主题创作的226位博主࿰…...

【CLIP系列】4:目标检测(ViLD、GLIP)
目录 1 ViLD2 GLIP2.1 前言2.2 损失计算2.3 模型框架 1 ViLD OPEN-VOCABULARY OBJECT DETECTION VIA VISION AND LANGUAGE KNOWLEDGE DISTILLATION 从标题就能看出来,作者是把CLIP模型当成一个Teacher,去蒸馏他自己的网络,从而能Zero Shot去…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...

【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...

【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...

Unity中的transform.up
2025年6月8日,周日下午 在Unity中,transform.up是Transform组件的一个属性,表示游戏对象在世界空间中的“上”方向(Y轴正方向),且会随对象旋转动态变化。以下是关键点解析: 基本定义 transfor…...