C语言内存管理详解
C语言不像其他高级语言那样提供自动内存管理,它要求程序员手动进行内存的分配和释放。在C语言中,动态内存的管理主要依赖于 malloc
、calloc
、realloc
和 free
等函数。理解这些函数的用法、内存泄漏的原因及其防止方法,对于编写高效、可靠的C程序至关重要。
本文将深入讲解C语言中的内存管理,涵盖动态内存分配、内存泄漏以及如何防止内存泄漏等内容。
推荐阅读:操作符详细解说,让你的编程技能更上一层楼
1. C语言动态内存分配
C语言提供了一些标准库函数,用来动态地分配和释放内存,这些函数位于 stdlib.h
头文件中。与栈上的静态内存分配不同,动态内存分配允许程序在运行时根据需求动态地分配内存。
1.1 malloc
函数
malloc
(memory allocation)函数用于分配指定大小的内存块,并返回该内存块的起始地址。它的原型如下:
void* malloc(size_t size);
- 参数:
size
是要分配的内存块的大小,单位是字节。 - 返回值:
malloc
返回一个指向已分配内存块的指针。如果内存分配失败,返回NULL
。
示例
#include <stdio.h>
#include <stdlib.h>int main() {int *ptr;// 动态分配一个整数的内存ptr = (int*)malloc(sizeof(int));if (ptr == NULL) {printf("Memory allocation failed!\n");return -1;}*ptr = 100; // 使用分配的内存printf("Value: %d\n", *ptr);free(ptr); // 释放内存return 0;
}
在上面的例子中,我们使用 malloc
分配了一个 int
类型的内存,并将其值设置为 100
,然后使用 free
释放了内存。
1.2 calloc
函数
calloc
(contiguous allocation)函数用于分配内存,但它与 malloc
不同的是,calloc
在分配内存后会初始化内存中的所有字节为零。它的原型如下:
void* calloc(size_t num, size_t size);
- 参数:
num
是需要分配的元素个数,size
是每个元素的大小(单位:字节)。 - 返回值:
calloc
返回指向已分配并初始化为零的内存块的指针。如果内存分配失败,返回NULL
。
示例
#include <stdio.h>
#include <stdlib.h>int main() {int *arr;int n = 5;// 动态分配一个包含5个整数的内存,并初始化为0arr = (int*)calloc(n, sizeof(int));if (arr == NULL) {printf("Memory allocation failed!\n");return -1;}for (int i = 0; i < n; i++) {printf("arr[%d] = %d\n", i, arr[i]);}free(arr); // 释放内存return 0;
}
在上面的例子中,calloc
被用来动态分配一个大小为 5 * sizeof(int)
字节的内存,并且将其初始化为零。
1.3 realloc
函数
realloc
(reallocation)函数用于重新调整之前分配的内存块的大小。它的原型如下:
void* realloc(void* ptr, size_t size);
- 参数:
ptr
是一个指向已分配内存的指针,size
是需要分配的新内存大小(单位:字节)。 - 返回值:
realloc
返回一个指向新内存块的指针。如果重新分配失败,返回NULL
,并且原来的内存块保持不变。如果ptr
为NULL
,realloc
的行为就等同于malloc
。
示例
#include <stdio.h>
#include <stdlib.h>int main() {int *arr;int n = 5;// 动态分配5个整数的内存arr = (int*)malloc(n * sizeof(int));if (arr == NULL) {printf("Memory allocation failed!\n");return -1;}// 修改数组大小,增加5个元素n = 10;arr = (int*)realloc(arr, n * sizeof(int));if (arr == NULL) {printf("Memory reallocation failed!\n");return -1;}for (int i = 0; i < n; i++) {printf("arr[%d] = %d\n", i, arr[i]);}free(arr); // 释放内存return 0;
}
在上面的例子中,我们先使用 malloc
分配了 5 个整数大小的内存,接着通过 realloc
将内存的大小扩大为 10 个整数。
1.4 free
函数
free
函数用于释放之前使用 malloc
、calloc
或 realloc
分配的内存。它的原型如下:
void free(void* ptr);
- 参数:
ptr
是指向之前分配的内存块的指针。如果ptr
为NULL
,free
不会执行任何操作。 - 返回值:
free
没有返回值。
示例
#include <stdio.h>
#include <stdlib.h>int main() {int *ptr = (int*)malloc(sizeof(int));if (ptr == NULL) {printf("Memory allocation failed!\n");return -1;}*ptr = 10;printf("Value: %d\n", *ptr);free(ptr); // 释放内存return 0;
}
2. 内存泄漏与防止
内存泄漏是指程序在运行过程中动态分配了内存空间,但没有及时释放它,导致这些内存空间无法再被访问和使用。内存泄漏会导致程序的内存使用不断增加,最终可能耗尽系统资源。
2.1 内存泄漏的原因
内存泄漏通常发生在以下几种情况下:
- 忘记调用
free
释放内存:分配了内存但没有调用free
释放。 - 提前丢失指针:在释放内存之前,指针被重新赋值,导致无法访问原来的内存块。
- 重复分配:在没有释放原有内存的情况下重新分配内存,导致原有内存无法访问。
2.2 防止内存泄漏的方法
-
确保每个
malloc
、calloc
或realloc
的调用都有相应的free
: 确保每次动态分配内存后,都能在适当的地方释放内存。 -
避免丢失指针: 在重新分配内存之前,确保保留原始指针。
ptr = (int*)malloc(sizeof(int)); if (ptr == NULL) {// 错误处理 } // 重新分配 int* new_ptr = (int*)realloc(ptr, new_size); if (new_ptr == NULL) {free(ptr); // 如果realloc失败,释放原内存 } else {ptr = new_ptr; }
-
使用内存泄漏检测工具: 工具如
valgrind
或AddressSanitizer
可以帮助开发者检测内存泄漏。 -
智能指针(C++): 如果使用 C++,可以使用智能指针(如
std::unique_ptr
和std::shared_ptr
)来自动管理内存。 -
清晰的内存管理策略: 每个函数在分配内存后,应该明确何时释放这部分内存,避免程序中多处使用相同内存块的情况。
3. 总结
动态内存管理是 C 语言编程中不可忽视的重要部分。通过 malloc
、calloc
、realloc
和 free
等函数,灵活地管理内存,避免内存溢出和内存泄漏等问题。防止内存泄漏的关键是确保每次分配的内存都有相应的释放,并且避免丢失指针,合理使用内存检测工具。
相关文章:

C语言内存管理详解
C语言不像其他高级语言那样提供自动内存管理,它要求程序员手动进行内存的分配和释放。在C语言中,动态内存的管理主要依赖于 malloc、calloc、realloc 和 free 等函数。理解这些函数的用法、内存泄漏的原因及其防止方法,对于编写高效、可靠的C…...

mysql从全备文件中提取单库或单表进行恢复——筑梦之路
前提条件 与业务确认涉及业务、数据库IP、数据误删除时间点、数据删除涉及的SCHEMA、数据表,确认该数据库为MySQLdump备份方式,备份策略为每日凌晨1点进行数据库全备份,备份保留7天,业务误删除数据时间点为当日10点左右࿰…...

HTML-新浪新闻-实现标题-排版
标题排版 图片标签:<img> src:指定图片的url(绝对路径/相对路径) width:图片的宽度(像素/相对于父元素的百分比) heigth:图片的高度(像素/相对于父元素的百分比&a…...

【前沿聚焦】机器学习的未来版图:从自动化到隐私保护的技术突破
网罗开发 (小红书、快手、视频号同名) 大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等…...

二叉树的最大深度(C语言详解版)
一、摘要 嗨喽呀大家,leetcode每日一题又和大家见面啦,今天要讲的是104.二叉树的最大深度,思路互相学习,有什么不足的地方欢迎指正!好啦让我们开始吧!!! 二、题目简介 给定一个二…...

基于dlib/face recognition人脸识别推拉流实现
目录 一.环境搭建 二.推拉流代码 三.人脸检测推拉流 一.环境搭建 1.下载RTSP服务器MediaMTX与FFmpeg FFmpeg是一款功能强大的开源多媒体处理工具,而MediaMTX则是一个轻量级的流媒体服务器。两者结合,可以实现将本地视频或者实时摄像头画面推送到RTSP流,从而实现视频…...

【kong gateway】5分钟快速上手kong gateway
kong gateway的请求响应示意图 安装 下载对应的docker 镜像 可以直接使用docker pull命令拉取,也可以从以下地址下载:kong gateway 3.9.0.0 docker 镜像 https://download.csdn.net/download/zhangshenglu1/90307400, postgres-13.tar http…...

webrtc入门系列(五)amazon-kinesis-video-streams-webrtc-sdk-c编译
《webrtc入门系列(一)easy_webrtc_server 入门环境搭建》 《webrtc入门系列(二)easy_webrtc_server 入门example测试》 《webrtc入门系列(三)云服务器coturn环境搭建》 《webrtc入门系列(四&…...

通过亚马逊云科技Bedrock打造自定义AI智能体Agent(上)
大家对于智能体代理Agent一定已经非常熟悉,自主代理(Autonomous Agents) 目前在AI行业极其热门并具有巨大的潜力,能够显著提升开发者日常的工作效率、自动化日常琐碎、重复性任务,并生成全新的内容。Agent可以理解用户…...

【Nacos】负载均衡
目录 前言 一、服务下线二、权重配置三、同一个集群优先访问四、环境隔离 前言 我们的生产环境相对是比较恶劣的,我们需要对服务的流量进行更加精细的控制.Nacos支持多种负载均衡策略,包括配置权重,同机房,同地域,同环…...

小智 AI 聊天机器人
小智 AI 聊天机器人 (XiaoZhi AI Chatbot) 👉参考源项目复现 👉 ESP32SenseVoiceQwen72B打造你的AI聊天伴侣!【bilibili】 👉 手工打造你的 AI 女友,新手入门教程【bilibili】 项目目的 本…...

HTML一般标签和自闭合标签介绍
在HTML中,标签用于定义网页内容的结构和样式。标签通常分为两类:一般标签(也称为成对标签或开放闭合标签)和自闭合标签(也称为空标签或自结束标签)。 以下是这两类标签的详细说明: 一、一般标…...

怎么用u盘怎么重装系统_用u盘重装系统详细图文教程【新手教程】
怎么用u盘怎么重装系统?如果需要重装操作系统的话,以往采用光盘使用的比较多,随着技术的进步,用u盘制作一个启动盘安装系统比较方便,只需要用u盘制作好pe启动盘就可以帮助别人安装系统了,那么用u盘怎么重装…...

记录一次k8s起不来的排查过程
我在k8s集群,重启了一个node宿主机,竟然发现kubelet起不来了!报错如下 这个报错很模糊,怎么排查呢。这样,开两个界面,一个重启kubelet,一个看系统日志(/var/log/message:centos,/va…...

代码练习2
求数组中的第二大值 #include <stdio.h> #include <stdlib.h> int main() {int arr[10]{1,9,2,8,7,3,4,6,5,10};int first, second,i;if (arr[0] > arr[1]) {first arr[0];second arr[1];} else {first arr[1];second arr[0];}for(i 2; i < 10; i) {if…...

2.1.3 第一个工程,点灯!
新建工程 点击菜单栏左上角,新建工程或者选择“文件”-“新建工程”,选择工程类型“标准工程”选择设备类型和编程语言,并指定工程文件名及保存路径,如下图所示: 选择工程类型为“标准工程” 选择主模块机型&#x…...

Qt Designer and Python: Build Your GUI
1.install pyside6 2.pyside6-designer.exe 发送到桌面快捷方式 在Python安装的所在 Scripts 文件夹下找到此文件。如C:\Program Files\Python312\Scripts 3. 打开pyside6-designer 设计UI 4.保存为simple.ui 文件,再转成py文件 用代码执行 pyside6-uic.exe simpl…...

蓝桥杯LQ1044 求完数
题目描述 因子:因子也叫因数,例如3515,那么3和5是15的因子。 同时15115,那么1和15也是15的因子。 1,3,5,15 这四个因子是15的所有因子。 完数:如果一个数等于不含它本身的其他因子之…...

消息队列篇--通信协议篇--TCP和UDP(3次握手和4次挥手,与Socket和webSocket的概念区别等)
1、TCP和UDP概述 TCP(传输控制协议,Transmission Control Protocol)和UDP(用户数据报协议,User Datagram Protocol)都算是最底层的通信协议,它们位于OSI模型的传输层。*传输层的主要职责是确保…...

YOLOv9改进,YOLOv9检测头融合ASFF(自适应空间特征融合),全网首发
摘要 一种新颖的数据驱动的金字塔特征融合策略,称为自适应空间特征融合 (ASFF)。它学习了在空间上过滤冲突信息以抑制不一致的方法,从而提高了特征的尺度不变性,并引入了几乎免费的推理开销。 # 理论介绍 目标检测在处理不同尺度的目标时,常采用特征金字塔结构。然而,…...

Elastic Agent 对 Kafka 的新输出:数据收集和流式传输的无限可能性
作者:来 Elastic Valerio Arvizzigno, Geetha Anne 及 Jeremy Hogan 介绍 Elastic Agent 的新功能:原生输出到 Kafka。借助这一最新功能,Elastic 用户现在可以轻松地将数据路由到 Kafka 集群,从而实现数据流和处理中无与伦比的可扩…...

论文速读|Is Cosine-Similarity of Embeddings Really About Similarity?WWW24
论文地址: https://arxiv.org/abs/2403.05440 https://dl.acm.org/doi/abs/10.1145/3589335.3651526 bib引用: inproceedings{Steck_2024, series{WWW ’24},title{Is Cosine-Similarity of Embeddings Really About Similarity?},url{http://dx.doi.o…...

Midjourney中的强变化、弱变化、局部重绘的本质区别以及其有多逆天的功能
开篇 Midjourney中有3个图片“微调”,它们分别为: 强变化;弱变化;局部重绘; 在Discord里分别都是用命令唤出的,但如今随着AI技术的发达在类似AI可人一类的纯图形化界面中,我们发觉这样的逆天…...

基于 Node.js 的天气查询系统实现(附源码)
项目概述 这是一个基于 Node.js 的全栈应用,前端使用原生 JavaScript 和 CSS,后端使用 Express 框架,通过调用第三方天气 API 实现天气数据的获取和展示。 主要功能 默认显示多个主要城市的天气信息 支持城市天气搜索 响应式布局设计 深色主题界面 优雅的加载动画 技术栈 …...

时序数据库的使用场景
文章目录 前言一、特点二、工作原理三、常见的时序数据库四、使用场景优势总结 前言 时序数据库(Time Series Database, TSDB) 是一种专门设计用于存储和处理时序数据的数据库。时序数据是指按照时间顺序排列的数据,其中每个数据点通常包含时…...

计算机的错误计算(二百二十二)
摘要 利用大模型化简计算 实验表明,虽然结果正确,但是,大模型既绕了弯路,又有数值计算错误。 与前面相同,再利用同一个算式看看另外一个大模型的化简与计算能力。 例1. 化简计算摘要中算式。 下面是与一个大模型的…...

ThinkPHP 8模型与数据的插入、更新、删除
【图书介绍】《ThinkPHP 8高效构建Web应用》-CSDN博客 《2025新书 ThinkPHP 8高效构建Web应用 编程与应用开发丛书 夏磊 清华大学出版社教材书籍 9787302678236 ThinkPHP 8高效构建Web应用》【摘要 书评 试读】- 京东图书 使用VS Code开发ThinkPHP项目-CSDN博客 编程与应用开…...

c语言函数(详解)
目录 前言 一、函数的基本概念和作用 二、函数的声明和定义 三、函数参数的传递方式 四、函数的递归 五、函数指针 总结 前言 本文主要讲解了c语言函数方面的内容 函数的定义和调用函数的返回值和参数函数的作用域和生命周期 函数的声明和定义 函数声明和函数定义的区别函数声…...

为AI聊天工具添加一个知识系统 之70 详细设计 之11 维度运动控制的应用:上下文受控的自然语言
本文要点 要点 前面我们 讨论了 “维度”及其运动控制原理 以及 维度控制 如何在中台微服务架构中撑起了“架构师”角色的一片天。下面我们从 “维度”运动控制的一个典型应用场景:受控的自然语言 ”开始讨论。 拼块文字型风格: 维度运动控制下的受控自然语言…...

ios打包:uuid与udid
ios的uuid与udid混乱的网上信息 新人开发ios,发现uuid和udid在网上有很多帖子里是混淆的,比如百度下,就会说: 在iOS中使用UUID(通用唯一识别码)作为永久签名,通常是指生成一个唯一标识…...