C语言 — 动态内存管理

article/2025/6/18 4:08:06

目录

  • 1.malloc和free函数
    • 1.1 malloc函数
    • 1.2 free函数
    • 1.3 malloc函数的使用
  • 2.calloc函数
    • 2.1 calloc函数
    • 2.2 calloc函数的使用
  • 3.realloc函数
    • 3.1 realloc函数
    • 3.2 realloc函数的使用
  • 4.动态内存管理笔试题
    • 4.1 笔试题(1)
    • 4.2 笔试题(2)
  • 5.柔性数组
    • 5.1 柔性数组定义
    • 5.2 柔性数组的使用

1.malloc和free函数

1.1 malloc函数

在这里插入图片描述
malloc函数的功能是向内存申请一块连续的内存空间,并将内容初始化为随机值,申请的大小是参数size,单位是字节,返回类型是void*类型的指针。

在这里插入图片描述
malloc函数的返回值:如果申请成功,会返回申请的内存空间起始位置的地址,如果申请失败会返回NULL(空指针).

1.2 free函数

在这里插入图片描述

free函数的功能是将开辟的内存空间释放,参数是开辟内存空间的起始地址,释放后参数ptr并不为NULL(空指针),因此使用free函数释放内存空间的同时,需要将ptr置为空指针;如果ptr本身为NULL,free函数不会执行。

1.3 malloc函数的使用

#include<stdio.h>
#include<stdlib.h>
//malloc函数的使用
int main()
{//开辟十个整型的空间大小//需要类型转换为int*类型的指针作为返回值int* ptr = (int*)malloc(10 * sizeof(int));//判断是否为NULL指针if (ptr == NULL){//输出错误原因perror("malloc");return 1;//终止程序}//使用for循环初始化int i = 0;for (i = 0; i < 10; i++){ptr[i] = i + 1;}//输出打印for (i = 0; i < 10; i++){printf("%d ", ptr[i]);}//释放内存空间free(ptr);ptr = NULL;//赋值为空指针return 0;
}

按F10启动调试观察malloc函数空间的开辟和释放的过程:观察开辟后内存空间的值
在这里插入图片描述
使用for循环初始化后的内容
在这里插入图片描述

输出初始化的内容1-10

在这里插入图片描述
按F10观察执行free函数后,开辟内存空间的内容,以及参数的变化

在这里插入图片描述

在使用free函数后需要及时将参数ptr置为空指针,否则会导致非法访问内存空间,导致程序奔溃。

在这里插入图片描述

2.calloc函数

2.1 calloc函数

在这里插入图片描述
calloc函数的功能与malloc一样,向内存申请一块连续的内存空间;与malloc函数不同的是,calloc函数有两个参数,第一个参数是元素个数,第二个参数是一个元素的大小,单位是字节,返回值是void*类型的指针。

在这里插入图片描述
如果开辟成功,返回开辟空间的起始地址,开辟失败,返回NULL(空指针)。

2.2 calloc函数的使用

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#pragma warning(disable:4996)//strcpy在VS中可能报警告,提示不安全,
//使用此指令可以不报警告,安全使用strcpy函数
//calloc的使用struct Stu
{char name[20];//名字int age;//年龄float score[3];//成绩
};
int main()
{//开辟1个结构体大小//需要类型转换为struct Stu*类型的指针作为返回值struct Stu* ptr = (struct Stu*)malloc(1 * sizeof(struct Stu));//第一个参数元素个数,第二个元素一个元素大小//判断是否为NULL指针if (ptr == NULL){//输出错误原因perror("calloc");return 1;//终止程序}float score1[3] = { 90.00f,85.50f,99.00f };//初始化strcpy((ptr->name,"Mary");//ptr->name表示name成员首元素地址ptr->age = 20;memcpy(ptr->score, score1,sizeof(score1));//ptr->score表示score成员首元素地址//输出打印printf(" name: %s\n age: %d\n score: %.2f  %.2f  %.2f",ptr->name, ptr->age, ptr->score[0], ptr->score[1], ptr->score[2]);//释放内存空间free(ptr);ptr = NULL;//赋值为空指针return 0;
}

按F10启动调试,观察calloc函数使用后内存空间的变化:使用calloc函数后,内存空间开辟成功,将内容初始化为随机值或者0。

在这里插入图片描述
初始化后
在这里插入图片描述

输出

在这里插入图片描述

free函数释放空间后,将参数置为空指针

在这里插入图片描述
在这里插入图片描述

3.realloc函数

3.1 realloc函数

在这里插入图片描述
realloc函数的功能是当开辟的内存空间不够或者多余时,进行内存空间的调整;第一个参数是调整空间的起始地址,第二个参数是调整后内存空间的大小,返回值是void*类型的指针。

在这里插入图片描述
在这里插入图片描述
如果开辟成功有两种情况,第一种是在原有的基础上,后面追加调整补充的空间,返回第一个参数的地址;第二种是重新开辟一块新的内存空间,将开辟的内存空间的起始地址返回;如果开辟失败返回空指针。

3.2 realloc函数的使用

#include<stdio.h>
#include<stdlib.h>
int main()
{//使用calloc开辟5个整型大小int* ptr = (int*)calloc(5, sizeof(int));//判断是否开辟失败if (ptr == NULL){perror("calloc");//输出错误内容return 1;}//调整为6个整型大小int* ptr1 = (int*)realloc(ptr, 6 * sizeof(int));if (ptr1 == NULL){//1.将原开辟的空间释放,并置空指针free(ptr);ptr = NULL;//2.输出错误信息perror("realloc");return 1;//终止程序}//释放内存空间,并置空指针free(ptr1);ptr1 = NULL;return 0;
}

按F10启动调试观察使用realloc函数后的内容变化:调用calloc函数后的内容

在这里插入图片描述

观察调用realloc函数后的内容

在这里插入图片描述
最后将空间释放,回收内存空间,最后不free(ptr)是因为,realloc函数在重新开辟新空间时,会将原有的参数开辟的空间释放,最后就不用再次释放,只需要释放调整后的内存空间。

在这里插入图片描述

4.动态内存管理笔试题

4.1 笔试题(1)

//以下程序的运行结果是什么?
#include <stdio.h>
#include <stdlib.h>
void GetMemory(char* p)
{p = (char*)malloc(100);
}
void Test(void)
{char* str = NULL;GetMemory(str);strcpy(str, "hello world");printf(str);
}
int main()
{Test();return 0;
}

在这里插入图片描述


程序运行的结果是程序崩溃,因为GetMemory函数传参str,使用char*p接收,p变量是str的一份临时拷贝,
改变形参不能改变实参的值,所以在调用strcpy函数函数时,str是NULL,导致程序终止。

4.2 笔试题(2)

//以下程序的运行结果是什么?存在什么问题?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void GetMemory(char** p, int num)
{*p = (char*)malloc(num);
}
void Test(void)
{char* str = NULL;GetMemory(&str, 100);strcpy(str, "hello");printf(str);
}
int main()
{Test();return 0;
}

程序可以正常输出hello,但是开辟内存空间后没有的释放内存空间,导致内存泄露。

在这里插入图片描述

5.柔性数组

5.1 柔性数组定义

柔性数组是存在于结构体中的最后一个成员,使用柔性数组的结构体必须至少包含两个成员,如下:

struct S
{int i;int arr[0];//柔性数组
};

sizeof计算时不会包含柔性数组的大小。

#include<stdio.h>
struct S
{int a;char ch[0];//柔性数组
};int main()
{printf("%zu", sizeof(struct S));return 0;
}

在这里插入图片描述

5.2 柔性数组的使用

#include<stdlib.h>struct Peo//人的结构体
{char name[20];//名字int age;//年龄char adress[20];//通讯地址char tele[12];//联系方式};
struct Contact//通讯录
{int count;//当前存储信息数量int capacity;//当前容量struct Peo data[0];//柔性数组(结构体数组)
};
int main()
{//开辟空间:一个整型和十个struct Peo大小struct Contact* ptr = (struct Contact*)malloc(sizeof(int) + 10 * sizeof(struct Peo));//判断if (ptr == 0){perror("malloc");return 1;}//使用//......//......//调整(内存空间不足时,根据count和capacity的值进行调整)//......//......//释放空间free(ptr);ptr = NULL;return 0;
}

柔性数组使用的好处:

1.灵活的内存管理‌:柔性数组允许结构体的最后一个成员是一个未知大小的数组。这意味着在动态分配内存时,可以根据实际需求来改变数组的长度,从而实现了内存的灵活管理‌。

2.提高访问速度‌:由于柔性数组直接作为结构体的一个成员,访问时不需要通过指针进行间接访问,这减少了访存次数,提高了访问速度‌。

‌3.减少内存碎片‌:通过动态分配内存,柔性数组可以更有效地利用内存空间,减少内存碎片的产生‌。


http://www.hkcw.cn/article/ciIXsVVXwq.shtml

相关文章

动态规划算法

简称 DP&#xff0c;是一种求解多阶段决策过程最优化问题的方法。在动态规划中&#xff0c;通过把原问题分解为相对简单的子问题&#xff0c;先求解子问题&#xff0c;再由子问题的解而得到原问题的解。 一、概念 动态规划最早由理查德 贝尔曼于 1957 年在其著作「动态规划&…

Qt -使用OpenCV得到SDF

博客主页&#xff1a;【夜泉_ly】 本文专栏&#xff1a;【暂无】 欢迎点赞&#x1f44d;收藏⭐关注❤️ 目录 cv::MatdistanceTransform获得SDF 本文的目标&#xff0c; 是简单学习并使用OpenCV的相关函数&#xff0c; 并获得QImage的SDF(Signed Distance Field 有向距离场) 至…

【小米拥抱AI】小米开源 MiMo-7B-RL-0530

更新日志 [2025.05.30] 在强化学习训练过程中&#xff0c;通过持续扩大训练窗口尺寸&#xff08;从32K提升至48K&#xff09;&#xff0c;MiMo-7B-RL-0530模型在AIME24基准测试上的表现持续提升&#xff0c;最终超越DeepSeek R1模型的性能水平。 BenchmarkMiMo-7B-RLMiMo-7B-…

俄布良斯克州桥梁坍塌致列车脱轨事故造成3死28伤

△图片来源:莫斯科交通检察院总台记者当地时间6月1日获悉,据俄罗斯紧急情况部初步统计,布良斯克州桥梁坍塌致火车脱轨事故共造成31人伤亡,其中3人不幸遇难,28人已送往医疗机构救治。此前据俄罗斯BAZA网站报道,事件造成4人死亡,至少44人受伤。俄紧急情况部称,救援人员正…

JDK17 与JDK8 共同存在一个电脑上

官网下载JDK17 官网链接 &#xff1a;https://www.oracle.com/java/technologies/downloads/#java17-windows 下载这个 安装 环境变量设置 因为之前设置过JDK 8这里为了使 两者共存&#xff0c;采用设置变量方式来实现具体操作如下 1、进入高级系统环境设置 1.1先建一个关…

打开NRODIC SDK编译不过怎么处理,keil与segger studio

打开NRODIC SDK编译不过怎么处理,以下是keil处理. 1,如图,不要安装安装也不会过 2. 不要安装点击否 3.点击确定后进来这个样子 4.这里选择这个勾,OK后就不会再有后面的pack_license 5.去掉勾后这里要选择自己SDK对应的pack版本,我的是8.27.0 6.OK后弹出个界面也要反复选择…

每日八股文5.31

每日八股-5.31 Go1.切片是值传递还是引用传递&#xff1f;2.切片的深拷贝与浅拷贝3.切片的底层实现4.切片的扩容机制5.Map是线程安全的吗&#xff1f;6.哪些类型可以作为map的key&#xff1f;7.Map删除一个key内存是否会释放&#xff1f;8.Map为什么是无序的&#xff1f;9.如何…

智能重塑连接:AI原生互联网的范式革命与未来十年

引言:互联网的下一幕——智能涌现与体验重塑 2024年初,OpenAI发布的文生视频模型Sora,以其惊人的逼真度和对物理世界的理解能力,再次将人工智能的魔力推向了全球聚光灯下。这不仅仅是一个技术演示,更像是一个强烈的信号:我们正加速驶向一个由AI深度重塑的未来。回望互联…

【深度学习相关安装及配环境】Anaconda搭建虚拟环境并安装CUDA、cuDVV和对应版本的Pytorch,并在jupyter notebook上部署

目录 1. 查看自己电脑的cuda版本2.安装cuda关于环境变量的配置测试一下&#xff0c;安装完成 3.安装cuDVV环境变量的配置测试一下&#xff0c;安装完成 4.创建虚拟环境先安装镜像源下载3.11版本py 5.在虚拟环境下&#xff0c;下载pytorch6.验证是否安装成功7.在jupyter noteboo…

2. 手写数字预测 gui版

2. 手写数字预测 gui版 背景1.界面绘制2.处理图片3. 加载模型4. 预测5.结果6.一点小问题 背景 做了手写数字预测的模型&#xff0c;但是老是跑模型太无聊了&#xff0c;就配合pyqt做了一个可视化界面出来玩一下 源代码可以去这里https://github.com/Leezed525/pytorch_toy拿 …

用JS实现植物大战僵尸(前端作业)

1. 先搭架子 整体效果&#xff1a; 点击开始后进入主场景 左侧是植物卡片 右上角是游戏的开始和暂停键 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevic…

巴黎球迷打出TIFO悼念恩里克女儿 感人至深的纪念

北京时间6月1日,巴黎圣日耳曼在欧冠决赛中以5-0战胜国际米兰,夺得本赛季欧冠冠军。赛后,安联球场展示了一个感人至深的TIFO,主角是巴黎圣日耳曼主教练恩里克和他的已故女儿Xana。十年前,恩里克带领巴塞罗那夺得欧冠冠军时,曾与女儿Xana一起将巴萨的旗帜插进球场。然而,X…

六一儿童节 实践我先行活动举行

5月30日,在“六一”国际儿童节来临之际,“实践我先行——2025年在宋庆龄奶奶生活过的地方过六一”活动在北京宋庆龄故居举行,逾百名中外少年儿童和教师代表参加。活动现场,北京市西城区金融街惠泽幼儿园的小朋友们表演了群鼓节目《华夏少年》。中国宋庆龄基金会党组书记、副…

阿什拉夫弑旧主 破门后拒绝庆祝 情深义重

在欧冠决赛中,巴黎圣日耳曼迎战国际米兰。上半场,阿什拉夫攻破了老东家的大门,帮助巴黎取得领先。这位现年26岁的摩洛哥后卫曾在2020年至2021年效力于国际米兰,并为蓝黑军团出场45次。比赛进行到第12分钟时,阿什拉夫推射空门得手,将比分改写为1-0。进球后,他举起双手,拒…

端午安康(Python)

端午节总算是回家了&#xff0c;感觉时间过得真快&#xff0c;马上就毕业了&#xff0c;用Python弄了一个端午节元素的界面&#xff0c;虽然有点不像&#xff0c;祝大家端午安康。端午节粽子&#xff08;python&#xff09;_python画粽子-CSDN博客https://blog.csdn.net/weixin…

10.安卓逆向2-frida hook技术-frida基本使用-frida指令(用于hook)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a;图灵Python学院 工具下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1bb8NhJc9eTuLzQr39lF55Q?pwdzy89 提取码&#xff1…

# CppCon 2014 学习: Quick game development with C++11/C++14

这是一个关于游戏开发与现代 C&#xff08;尤其是 C11/C14&#xff09;结合的技术分享或讲座的概要&#xff0c;结构清晰、内容分为几个部分&#xff1a; About This Talk — 内容结构 1. 导言部分&#xff08;Introductory part&#xff09; 介绍为什么选择游戏开发作为主题…

vscode不满足先决条件问题的解决——vscode的老版本安装与禁止更新(附安装包)

目录 起因 vscode更新设置的关闭 安装包 结语 起因 由于主包用的系统是centos的&#xff0c;且版本有点老了&#xff0c;再加上vscode现在不支持老版本的&#xff0c;这对主包来说更是雪上加霜啊 但是主包看了网上很多教程&#xff0c;眼花缭乱&#xff0c;好多配置要改&…

如何手搓扫雷(待扩展)

文章目录 一、扫雷游戏分析与设计1.1 扫雷游戏的功能说明1.2 游戏的分析和设计1.2.1 数据结构的分析1.2.2 文件结构设计 二、扫雷游戏的代码实现三、扫雷游戏的扩展总结 一、扫雷游戏分析与设计 扫雷游戏网页版 1.1 扫雷游戏的功能说明 使用控制台&#xff08;黑框框的程序&a…

Python打卡训练营学习记录Day41

DAY 41 简单CNN 知识回顾 数据增强卷积神经网络定义的写法batch归一化&#xff1a;调整一个批次的分布&#xff0c;常用与图像数据特征图&#xff1a;只有卷积操作输出的才叫特征图调度器&#xff1a;直接修改基础学习率 卷积操作常见流程如下&#xff1a; 1. 输入 → 卷积层 →…