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去…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...
中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...
Caliper 配置文件解析:fisco-bcos.json
config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...
