当前位置: 首页 > news >正文

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)

堆内存是程序员通过内存分配函数(如 malloccallocrealloc)动态分配的内存,直到程序显式调用 free 函数释放它。堆内存不受栈的大小限制,程序员可以根据需要申请任意大小的内存,适用于处理动态内存需求较大的场景。

堆内存的特点:
  • 手动管理:堆内存需要程序员手动管理,程序员需要显式地调用 malloccallocrealloc 等函数进行分配,使用后需要通过 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 标准引入了柔性数组,它允许在结构体中定义一个没有确定大小的数组。柔性数组通常位于结构体的最后一个成员,编译器会将其视为一个不确定大小的数组。柔性数组通常与动态内存分配(如 malloccalloc)一起使用,以便分配合适大小的内存。

示例:
#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++程序的内存是如何开辟的?

&#x1f4ac; 欢迎讨论&#xff1a;在阅读过程中有任何疑问&#xff0c;欢迎在评论区留言&#xff0c;我们一起交流学习&#xff01; &#x1f44d; 点赞、收藏与分享&#xff1a;如果你觉得这篇文章对你有帮助&#xff0c;记得点赞、收藏&#xff0c;并分享给更多对C语言感兴…...

日志结构化处理:PO对象toString日志转JSON工具

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

python学opencv|读取图像(六十五)使用cv2.boundingRect()函数实现图像轮廓矩形标注

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

大疆无人机需要的kml文件如何制作kml导出(大疆KML文件)

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

ArrayList、LinkedList、HashMap、HashTable、HashSet、TreeSet

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

手动配置IP

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

idea如何使用AI编程提升效率-在IntelliJ IDEA 中安装 GitHub Copilot 插件的步骤-卓伊凡

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

游戏引擎学习第101天

回顾当前情况 昨天的进度基本上完成了所有内容&#xff0c;但我们还没有进行调试。虽然我们在运行时做的事情大致上是对的&#xff0c;但还是存在一些可能或者确定的bug。正如昨天最后提到的&#xff0c;既然现在时间晚了&#xff0c;就不太适合开始调试&#xff0c;所以今天我…...

css块级元素和行内元素区别

在CSS中&#xff0c;元素可以分为两大类&#xff1a;块级元素&#xff08;Block-level elements&#xff09;和行内元素&#xff08;Inline elements&#xff09;。这两种元素在网页布局中起着不同的作用&#xff0c;主要体现在它们的显示方式、尺寸控制、以及与其他元素的交互…...

JAVA安全—Shiro反序列化DNS利用链CC利用链AES动态调试

前言 讲了FastJson反序列化的原理和利用链&#xff0c;今天讲一下Shiro的反序列化利用&#xff0c;这个也是目前比较热门的。 原生态反序列化 我们先来复习一下原生态的反序列化&#xff0c;之前也是讲过的&#xff0c;打开我们写过的serialization_demo。代码也很简单&…...

什么是信息熵

信息熵 公式 一个离散随机变量 X X X的可能取值为 X x 1 , x 2 , . . . , x n Xx_1,x_2,...,x_n Xx1​,x2​,...,xn​&#xff0c;而对应的概率为 p i p ( X x i ) p_ip(Xx_i) pi​p(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 xn​p( x …...

使用API有效率地管理Dynadot域名,清除某一文件夹中域名的默认DNS设置

关于Dynadot Dynadot是通过ICANN认证的域名注册商&#xff0c;自2002年成立以来&#xff0c;服务于全球108个国家和地区的客户&#xff0c;为数以万计的客户提供简洁&#xff0c;优惠&#xff0c;安全的域名注册以及管理服务。 Dynadot平台操作教程索引&#xff08;包括域名邮…...

2.11 sqlite3数据库【数据库的相关操作指令、函数】

练习&#xff1a; 将 epoll 服务器 客户端拿来用 客户端&#xff1a;写一个界面&#xff0c;里面有注册登录 服务器&#xff1a;处理注册和登录逻辑&#xff0c;注册的话将注册的账号密码写入数据库&#xff0c;登录的话查询数据库中是否存在账号&#xff0c;并验证密码是否正确…...

当 LSTM 遇上 ARIMA!!

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

kali连接xshell

1.先保证宿主机&#xff1a;以太网适配器 VMware Network Adapter VMnet8 和kali&#xff08;net 模式&#xff09;在同一个网段 windows VMnet8开启 查看是否是自动获取ip ipv4 和ipv6一样的 查看 windows VMnet8的IPv4的地址 查看 kali 的IP地址 window ping的结果&#xf…...

图像曲率滤波

看到这么一个非常有意思的东西&#xff0c;记录一下 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 可以绑定相同的端口吗?

前言 当一个网络接口接收到一个数据报时&#xff0c;IP 模块首先检查目的地址是否为自己的 IP 地址&#xff0c;如果是的话&#xff0c;数据报交付给由 IPv4 头部的协议字段指定的协议模块。 TCP 和 UDP 在内核中是两个完全独立的模块&#xff0c;送给 TCP/UDP 模块的报文根据…...

【Python网络爬虫】爬取网站图片实战

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

2024年博客之星年度评选—创作影响力评审+主题文章创作评审目前排名(2024博客之星陪跑小分队助力2024博客之星创作者成长)

2024年博客之星年度评选—创作影响力评审主题文章创作评审目前排名 2024年博客之星主题文章创作评审文章得分公布&#xff01;2024年博客之星创作影响力评审2024年博客之星主题文章创作评审目前排名公布&#xff01; 【2024博客之星】恭喜完成✅主题创作的226位博主&#xff0…...

【CLIP系列】4:目标检测(ViLD、GLIP)

目录 1 ViLD2 GLIP2.1 前言2.2 损失计算2.3 模型框架 1 ViLD OPEN-VOCABULARY OBJECT DETECTION VIA VISION AND LANGUAGE KNOWLEDGE DISTILLATION 从标题就能看出来&#xff0c;作者是把CLIP模型当成一个Teacher&#xff0c;去蒸馏他自己的网络&#xff0c;从而能Zero Shot去…...

避开C2000开发第一个坑:TMS320F28069的InitSysCtrl()函数里,为什么ADC时钟要开一下又关?

TMS320F28069开发揭秘&#xff1a;ADC时钟瞬启瞬闭背后的硬件校准逻辑 在TMS320F28069的InitSysCtrl()初始化函数中&#xff0c;有一段看似矛盾的代码操作&#xff1a;先启用ADC时钟&#xff0c;调用(*Device_cal)()函数后立即关闭。这个"开关ADC时钟"的瞬态操作绝非…...

高级技巧:利用SharpShooter实现COM Staging和应用程序白名单绕过

高级技巧&#xff1a;利用SharpShooter实现COM Staging和应用程序白名单绕过 【免费下载链接】SharpShooter Payload Generation Framework 项目地址: https://gitcode.com/gh_mirrors/sh/SharpShooter SharpShooter 是一款功能强大的Payload生成框架&#xff0c;专为安…...

《QGIS空间数据处理与高级制图》005:第三方预处理插件推荐

作者:翰墨之道,毕业于国际知名大学空间信息与计算机专业,获硕士学位,现任国内时空智能领域资深专家、CSDN知名技术博主。多年来深耕地理信息与时空智能核心技术研发,精通 QGIS、GrassGIS、OSG、OsgEarth、UE、Cesium、OpenLayers、Leaflet、MapBox 等主流工具与框架,兼具…...

RPG Maker MV终极插件合集:100+免费插件打造专业级游戏体验

RPG Maker MV终极插件合集&#xff1a;100免费插件打造专业级游戏体验 【免费下载链接】RPGMakerMV RPGツクールMV、MZで動作するプラグインです。 项目地址: https://gitcode.com/gh_mirrors/rp/RPGMakerMV 你是否曾经为RPG Maker MV的功能限制感到困扰&#xff1f;想要…...

Vcpkg不只是个安装器:在Windows上用它为你的C++项目打造可复现的构建环境

Vcpkg工程化实践&#xff1a;构建可复现的C开发环境 在大型C项目中&#xff0c;依赖管理一直是开发者面临的痛点之一。不同团队成员使用不同版本的第三方库&#xff0c;CI服务器上的构建环境与本地开发环境不一致&#xff0c;这些问题常常导致"在我机器上能运行"的尴…...

从IR2184到全桥驱动:搞懂H桥电路防短路与死区设置(附电路图分析)

从IR2184到全桥驱动&#xff1a;H桥电路防短路与死区设置的工程实践 在电机控制系统中&#xff0c;H桥电路的设计可靠性直接决定了整个驱动方案的成败。许多工程师在初次设计基于IR2184的全桥驱动时&#xff0c;往往会被"上下桥臂直通"问题困扰——这种短路状态能在微…...

基于Athena-Public框架的LLM全栈应用开发实践与架构解析

1. 项目概述与核心价值 最近在梳理一些开源项目时&#xff0c;发现了一个名为“Athena-Public”的仓库&#xff0c;作者是winstonkoh87。这个项目名听起来就很有意思&#xff0c;Athena&#xff08;雅典娜&#xff09;是智慧女神&#xff0c;一个公开的“智慧”项目&#xff0c…...

【Docker】解放C盘空间:在Win10上利用WSL2迁移Docker镜像存储路径实战

1. 为什么需要迁移Docker镜像存储路径&#xff1f; 很多Windows 10用户在使用Docker进行开发时都会遇到一个头疼的问题&#xff1a;C盘空间莫名其妙就被占满了。我自己就曾经遇到过这种情况&#xff0c;明明没装多少软件&#xff0c;C盘却显示只剩下几个GB的空间。后来发现罪魁…...

暗黑3一键战斗终极指南:5步掌握D3KeyHelper宏工具

暗黑3一键战斗终极指南&#xff1a;5步掌握D3KeyHelper宏工具 【免费下载链接】D3keyHelper D3KeyHelper是一个有图形界面&#xff0c;可自定义配置的暗黑3鼠标宏工具。 项目地址: https://gitcode.com/gh_mirrors/d3/D3keyHelper 想要在暗黑破坏神3中告别重复按键的疲惫…...

用树莓派+Python玩转无源蜂鸣器:手把手教你编一首《欢乐颂》(代码可调)

用树莓派Python玩转无源蜂鸣器&#xff1a;手把手教你编一首《欢乐颂》&#xff08;代码可调&#xff09; 在创客圈里&#xff0c;树莓派一直被誉为"万能小板"&#xff0c;而Python则是入门门槛最低的编程语言之一。当这两者相遇&#xff0c;再搭配上一个简单的无源蜂…...