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

C语言内存管理详解

C语言不像其他高级语言那样提供自动内存管理,它要求程序员手动进行内存的分配和释放。在C语言中,动态内存的管理主要依赖于 malloccallocreallocfree 等函数。理解这些函数的用法、内存泄漏的原因及其防止方法,对于编写高效、可靠的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,并且原来的内存块保持不变。如果 ptrNULLrealloc 的行为就等同于 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 函数用于释放之前使用 malloccallocrealloc 分配的内存。它的原型如下:

void free(void* ptr);
  • 参数ptr 是指向之前分配的内存块的指针。如果 ptrNULLfree 不会执行任何操作。
  • 返回值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 内存泄漏的原因

内存泄漏通常发生在以下几种情况下:

  1. 忘记调用 free 释放内存:分配了内存但没有调用 free 释放。
  2. 提前丢失指针:在释放内存之前,指针被重新赋值,导致无法访问原来的内存块。
  3. 重复分配:在没有释放原有内存的情况下重新分配内存,导致原有内存无法访问。
2.2 防止内存泄漏的方法
  1. 确保每个 malloccallocrealloc 的调用都有相应的 free: 确保每次动态分配内存后,都能在适当的地方释放内存。

  2. 避免丢失指针: 在重新分配内存之前,确保保留原始指针。

    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;
    }
    
  3. 使用内存泄漏检测工具: 工具如 valgrindAddressSanitizer 可以帮助开发者检测内存泄漏。

  4. 智能指针(C++): 如果使用 C++,可以使用智能指针(如 std::unique_ptrstd::shared_ptr)来自动管理内存。

  5. 清晰的内存管理策略: 每个函数在分配内存后,应该明确何时释放这部分内存,避免程序中多处使用相同内存块的情况。

3. 总结

动态内存管理是 C 语言编程中不可忽视的重要部分。通过 malloccallocreallocfree 等函数,灵活地管理内存,避免内存溢出和内存泄漏等问题。防止内存泄漏的关键是确保每次分配的内存都有相应的释放,并且避免丢失指针,合理使用内存检测工具。

相关文章:

C语言内存管理详解

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

mysql从全备文件中提取单库或单表进行恢复——筑梦之路

前提条件 与业务确认涉及业务、数据库IP、数据误删除时间点、数据删除涉及的SCHEMA、数据表&#xff0c;确认该数据库为MySQLdump备份方式&#xff0c;备份策略为每日凌晨1点进行数据库全备份&#xff0c;备份保留7天&#xff0c;业务误删除数据时间点为当日10点左右&#xff0…...

HTML-新浪新闻-实现标题-排版

标题排版 图片标签&#xff1a;<img> src&#xff1a;指定图片的url&#xff08;绝对路径/相对路径&#xff09; width&#xff1a;图片的宽度&#xff08;像素/相对于父元素的百分比&#xff09; heigth&#xff1a;图片的高度&#xff08;像素/相对于父元素的百分比&a…...

【前沿聚焦】机器学习的未来版图:从自动化到隐私保护的技术突破

网罗开发 &#xff08;小红书、快手、视频号同名&#xff09; 大家好&#xff0c;我是 展菲&#xff0c;目前在上市企业从事人工智能项目研发管理工作&#xff0c;平时热衷于分享各种编程领域的软硬技能知识以及前沿技术&#xff0c;包括iOS、前端、Harmony OS、Java、Python等…...

二叉树的最大深度(C语言详解版)

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

基于dlib/face recognition人脸识别推拉流实现

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

【kong gateway】5分钟快速上手kong gateway

kong gateway的请求响应示意图 安装 下载对应的docker 镜像 可以直接使用docker pull命令拉取&#xff0c;也可以从以下地址下载&#xff1a;kong gateway 3.9.0.0 docker 镜像 https://download.csdn.net/download/zhangshenglu1/90307400&#xff0c; postgres-13.tar http…...

webrtc入门系列(五)amazon-kinesis-video-streams-webrtc-sdk-c编译

《webrtc入门系列&#xff08;一&#xff09;easy_webrtc_server 入门环境搭建》 《webrtc入门系列&#xff08;二&#xff09;easy_webrtc_server 入门example测试》 《webrtc入门系列&#xff08;三&#xff09;云服务器coturn环境搭建》 《webrtc入门系列&#xff08;四&…...

通过亚马逊云科技Bedrock打造自定义AI智能体Agent(上)

大家对于智能体代理Agent一定已经非常熟悉&#xff0c;自主代理&#xff08;Autonomous Agents&#xff09; 目前在AI行业极其热门并具有巨大的潜力&#xff0c;能够显著提升开发者日常的工作效率、自动化日常琐碎、重复性任务&#xff0c;并生成全新的内容。Agent可以理解用户…...

【Nacos】负载均衡

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

小智 AI 聊天机器人

小智 AI 聊天机器人 &#xff08;XiaoZhi AI Chatbot&#xff09; &#x1f449;参考源项目复现 &#x1f449; ESP32SenseVoiceQwen72B打造你的AI聊天伴侣&#xff01;【bilibili】 &#x1f449; 手工打造你的 AI 女友&#xff0c;新手入门教程【bilibili】 项目目的 本…...

HTML一般标签和自闭合标签介绍

在HTML中&#xff0c;标签用于定义网页内容的结构和样式。标签通常分为两类&#xff1a;一般标签&#xff08;也称为成对标签或开放闭合标签&#xff09;和自闭合标签&#xff08;也称为空标签或自结束标签&#xff09;。 以下是这两类标签的详细说明&#xff1a; 一、一般标…...

怎么用u盘怎么重装系统_用u盘重装系统详细图文教程【新手教程】

怎么用u盘怎么重装系统&#xff1f;如果需要重装操作系统的话&#xff0c;以往采用光盘使用的比较多&#xff0c;随着技术的进步&#xff0c;用u盘制作一个启动盘安装系统比较方便&#xff0c;只需要用u盘制作好pe启动盘就可以帮助别人安装系统了&#xff0c;那么用u盘怎么重装…...

记录一次k8s起不来的排查过程

我在k8s集群&#xff0c;重启了一个node宿主机&#xff0c;竟然发现kubelet起不来了&#xff01;报错如下 这个报错很模糊&#xff0c;怎么排查呢。这样&#xff0c;开两个界面&#xff0c;一个重启kubelet&#xff0c;一个看系统日志(/var/log/message:centos&#xff0c;/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 第一个工程,点灯!

新建工程 点击菜单栏左上角&#xff0c;新建工程或者选择“文件”-“新建工程”&#xff0c;选择工程类型“标准工程”选择设备类型和编程语言&#xff0c;并指定工程文件名及保存路径&#xff0c;如下图所示&#xff1a; 选择工程类型为“标准工程” 选择主模块机型&#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 文件&#xff0c;再转成py文件 用代码执行 pyside6-uic.exe simpl…...

蓝桥杯LQ1044 求完数

题目描述 因子&#xff1a;因子也叫因数&#xff0c;例如3515&#xff0c;那么3和5是15的因子。 同时15115&#xff0c;那么1和15也是15的因子。 1&#xff0c;3&#xff0c;5&#xff0c;15 这四个因子是15的所有因子。 完数&#xff1a;如果一个数等于不含它本身的其他因子之…...

消息队列篇--通信协议篇--TCP和UDP(3次握手和4次挥手,与Socket和webSocket的概念区别等)

1、TCP和UDP概述 TCP&#xff08;传输控制协议&#xff0c;Transmission Control Protocol&#xff09;和UDP&#xff08;用户数据报协议&#xff0c;User Datagram Protocol&#xff09;都算是最底层的通信协议&#xff0c;它们位于OSI模型的传输层。*传输层的主要职责是确保…...

YOLOv9改进,YOLOv9检测头融合ASFF(自适应空间特征融合),全网首发

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

Elastic Agent 对 Kafka 的新输出:数据收集和流式传输的无限可能性

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

论文速读|Is Cosine-Similarity of Embeddings Really About Similarity?WWW24

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

Midjourney中的强变化、弱变化、局部重绘的本质区别以及其有多逆天的功能

开篇 Midjourney中有3个图片“微调”&#xff0c;它们分别为&#xff1a; 强变化&#xff1b;弱变化&#xff1b;局部重绘&#xff1b; 在Discord里分别都是用命令唤出的&#xff0c;但如今随着AI技术的发达在类似AI可人一类的纯图形化界面中&#xff0c;我们发觉这样的逆天…...

基于 Node.js 的天气查询系统实现(附源码)

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

时序数据库的使用场景

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

计算机的错误计算(二百二十二)

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

ThinkPHP 8模型与数据的插入、更新、删除

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

c语言函数(详解)

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

为AI聊天工具添加一个知识系统 之70 详细设计 之11 维度运动控制的应用:上下文受控的自然语言

本文要点 要点 前面我们 讨论了 “维度”及其运动控制原理 以及 维度控制 如何在中台微服务架构中撑起了“架构师”角色的一片天。下面我们从 “维度”运动控制的一个典型应用场景&#xff1a;受控的自然语言 ”开始讨论。 拼块文字型风格: 维度运动控制下的受控自然语言…...

ios打包:uuid与udid

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