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

动态内存管理—C语言通讯录

目录

一,动态内存函数的介绍

1.1 malloc和free

1.2 calloc

1.3 realloc

1.4C/C++程序的内存开辟

二,通讯录管理系统


动态内存函数的介绍

malloc

free

calloc

realloc

一,动态内存函数的介绍

1.1 malloc和free

void* malloc ( size_t size );
这个函数向内存申请一块连续可用的空间,并返回指向这块空间的指针。
如果开辟成功,则返回一个指向开辟好空间的指针。
如果开辟失败,则返回一个NULL 指针,因此 malloc的返回值一定要做检查。
返回值的类型是 void* ,所以 malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己来决定。
如果参数 size 0 malloc的行为是标准是未定义的,取决于编译器。
void free ( void* ptr );
free 函数用来释放动态开辟的内存。
如果参数 ptr 指向的空间不是动态开辟的,那 free 函数的行为是未定义的。
如果参数 ptr NULL 指针,则函数什么事都不做。
可以看到,free之后将向内存申请的空间给释放了,当然不要忘了将他设置为NULL防止野指针的使用,当然如果不释放的话会出现内存泄漏的问题,我们的电脑把程序关了,就退出了,我们申请的空间也就被释放的,但是有些服务器是一直不关的,那如果在使用时一直内存泄漏会出现问题的。

1.2 calloc

void* calloc ( size_t num , size_t size );
函数的功能是为 num 个大小为 size 的元素开辟一块空间,并且把空间的每个字节初始化为 0
与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全 0

例如:

1.3 realloc

realloc 函数的出现让动态内存管理更加灵活。
有时会我们发现过去申请的空间太小了,有时候我们又会觉得申请的空间过大了,那为了合理的时候内存,我们一定会对内存的大小做灵活的调整。那 realloc 函数就可以做到对动态开辟内存大小的调整。
void* realloc ( void* ptr , size_t size );
ptr 是要调整的内存地址
size 调整之后新大小
返回值为调整之后的内存起始位置。
这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到 的空间。
realloc 在调整内存空间的是存在两种情况
情况 1 :原有空间之后有足够大的空间
情况 2 :原有空间之后没有足够大的空间
情况 1
当是情况 1 的时候,要扩展内存就直接原有内存之后直接追加空间,原来空间的数据不发生变化。
情况 2
当是情况 2 的时候,原有空间之后没有足够多的空间时,扩展的方法是:在堆空间上另找一个合适大小的连续空间来使用。这样函数返回的是一个新的内存地址。

将刚刚malloc的空间扩大了2呗,当然指针在给p1之前是需要判断是否开辟成功的,如果没有足够的空间去开辟的话,realloc是会返回NULL指针的,如果用p1去接受,那么就会找不到原来的地址进而导致内存泄漏。

1.4C/C++程序的内存开辟

1. 栈区(stack):在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结
束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是
分配的内存容量有限。 栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返
回地址等。
2. 堆区(heap):一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。分
配方式类似于链表。
3. 数据段(静态区)(static)存放全局变量、静态数据。程序结束后由系统释放。
4. 代码段:存放函数体(类成员函数和全局函数)的二进制代码

二,通讯录管理系统

头文件:

contact.h

#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<stdlib.h>
//通讯录信息包含姓名,年龄,性别,电话,住址
typedef struct PeoInfo
{char name[20];int age;char sex[10];char tele[12];char addr[30];
}PeoInfo;
typedef struct Contact
{//每个人的信息PeoInfo* data;//当天通讯录存储的个数int count;//当前通讯录的容量int capacity;
}Contact;//销毁通讯录
void DestoryContact(Contact* pc);
//初始化通讯录
void InitContact(Contact* pc);//增加通讯录信息
void AddContact(Contact* pc);//打印通讯录的内容
void ShowContact(Contact* pc);
//删除通讯录的内容
void DelContact(Contact* pc);
//查找通讯录的信息
void SearchContact(Contact* pc);
//修改通讯录的信息
void ModifyContact(Contact* pc);
//排序通讯录的内容
void SortContact(Contact* pc);
contact.c文件
#include"contact.h"//初始化通讯录
void InitContact(Contact* pc)
{//断言,pc不为空assert(pc);//初始时我们给通讯录两个大小的空间Contact* temp = (PeoInfo*)calloc(2, sizeof(PeoInfo));//如果开辟成功这将if (temp){pc->data = temp;pc->capacity = 2;pc->count = 0;}
}//检测通讯录容量
void Checkcapacity(Contact* pc)
{//如果当前容量等于我们的存放信息的个数那么我们就扩容if (pc->capacity == pc->count){Contact* temp = (Contact*)realloc(pc->data, sizeof(PeoInfo) * 4);if (temp){pc = temp;//每次增容成功会都要增加capacity的值pc->capacity = pc->capacity + 4;printf("增容成功\n");}}
}//增加联系人
void AddContact(Contact* pc)
{assert(pc);//判断通讯录是否已满Checkcapacity(pc);//添加信息printf("请输入姓名:>");scanf("%s", pc->data[pc->count].name);printf("请输入年龄:>");scanf("%d", &pc->data[pc->count].age);printf("请输入性别:>");scanf("%s", pc->data[pc->count].sex);printf("请输入电话:>");scanf("%s", pc->data[pc->count].tele);printf("请输入住址:>");scanf("%s", pc->data[pc->count].addr);//每次添加联系人之后要将count+1pc->count++;printf("添加成功\n");
}//销毁通讯录
void DestoryContact(Contact* pc)
{//释放我们申请的空间free(pc->data);pc->data = NULL;
}//展示通讯录的信息
void ShowContact(Contact* pc)
{assert(pc);int i = 0;printf("%-10s%-10s%-10s%-12s%-10s\n", "姓名", "年龄", "性别", "电话", "住址");for (i = 0; i < pc->count; i++){printf("%-10s%-10d%-10s%-20s%-15s", pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].tele,pc->data[i].addr);printf("\n");}}//查找通讯录里面是否有这个 不考虑重名问题
int find_by_name(Contact* pc, char name[])
{assert(pc);int i = 0;for (i = 0; i < pc->count; i++){if (strcmp(pc->data[i].name, name) == 0){return i;}}return -1;
}//删除通讯录中某个人的信息
void DelContact(Contact* pc)
{assert(pc);printf("请输入要删除人的姓名:>");char name[20] = { 0 };//如果通讯录中没有信息if (pc->count == 0){printf("通讯录中没有信息可删除\n");return;}scanf("%s", name);//查找信息int pos = find_by_name(pc, name);if (pos == -1){printf("要删除的人不存在\n");return;}//删除信息int i = 0;for (i = pos; i <= pc->count - 1; i++){pc->data[pos] = pc->data[pos + 1];}pc->count--;printf("删除成功\n");
}//查找通讯录中的某个人
void SearchContact(Contact* pc)
{assert(pc);if (pc->count == 0){printf("通讯录中没有信息可删除\n");return;}char name[20] = { 0 };printf("请输入你要查找人的名字:>");scanf("%s", name);int pos = find_by_name(pc, name);if (pos == -1){printf("要删除的人不存在\n");return;}printf("要查找人的信息如下:>\n");printf("%-10s%-10s%-10s%-12s%-10s\n", "姓名", "年龄", "性别", "电话", "住址");printf("%-10s%-10d%-10s%-20s%-15s", pc->data[pos].name,pc->data[pos].age,pc->data[pos].sex,pc->data[pos].tele,pc->data[pos].addr);printf("\n");
}//修改通讯录中某个人信息
void ModifyContact(Contact* pc)
{assert(pc);if (pc->count == 0){printf("通讯录中没有信息可修改\n");return;}char name[20] = { 0 };//查找printf("请输入你要修改信息人的名子:>");scanf("%s", name);int pos = find_by_name(pc, name);if (pos == -1){printf("要修改的人的信息不存在\n");return;}//修改printf("请输入你要修改的内容:\n");printf("请输入姓名:>");scanf("%s", pc->data[pos].name);printf("请输入年龄:>");scanf("%d", &pc->data[pos].age);printf("请输入性别:>");scanf("%s", pc->data[pos].sex);printf("请输入电话:>");scanf("%s", pc->data[pos].tele);printf("请输入住址:>");scanf("%s", pc->data[pos].addr);printf("修改成功\n");
}//给qsort函数的比较函数
int cmp_by_name(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
//排序我们的通讯录,按照名字排序
void SortContact(Contact* pc)
{assert(pc);qsort(pc->data, pc->count, sizeof(PeoInfo), cmp_by_name);printf("排序成功\n");
}
test.c
#include "contact.h"void menu()
{printf("**************************************\n");printf("**************************************\n");printf("*******  1.add     2.Del    **********\n");printf("*******  3.search  4.modify **********\n");printf("*******  5.show    6.sort   **********\n");printf("*******  0.exit             **********\n");printf("**************************************\n");printf("**************************************\n");
}
int main()
{int input = 0;Contact con;InitContact(&con);do{   //打印菜单做提示menu();printf("请选择:>");scanf("%d", &input);switch (input){case 1:AddContact(&con);break;case 2:DelContact(&con);break;case 3:SearchContact(&con);break;case 4:ModifyContact(&con);break;case 5:ShowContact(&con);break;case 6:SortContact(&con);break;case 0:printf("退出程序\n");DestoryContact(&con);break;default:printf("选择错误请重新选择:>");break;}} while (input);return 0;
}

相关文章:

动态内存管理—C语言通讯录

目录 一&#xff0c;动态内存函数的介绍 1.1 malloc和free 1.2 calloc 1.3 realloc 1.4C/C程序的内存开辟 二&#xff0c;通讯录管理系统 动态内存函数的介绍 malloc free calloc realloc 一&#xff0c;动态内存函数的介绍 1.1 malloc和free void* malloc (…...

美光EMMC芯片丝印型号查询 8LK17/D9PSK, OXA17/JY997

问题说明 最近在使用美光EMMC的时候&#xff0c;发现通过芯片丝印查询不到 芯片的规格说明书&#xff1b; 经过查阅资料&#xff0c;发现美光的EMMC芯片 “由于空间限制&#xff0c;FBGA 封装组件具有与部件号不同的缩写部件标记”&#xff0c;需要通过官网查询丝印的FBGA cod…...

win32-鼠标消息、键盘消息、计时器消息、菜单资源

承接前文&#xff1a; win32窗口编程windows 开发基础win32-注册窗口类、创建窗口win32-显示窗口、消息循环、消息队列 本文目录 键盘消息键盘消息的分类WM_CHAR 字符消息 鼠标消息鼠标消息附带信息 定时器消息 WM_TIMER创建销毁定时器 菜单资源资源相关菜单资源使用命令消息的…...

springboot项目部署到linux服务器

springboot后端 修改前 修改后 vue前端 修改前 将地址中的 localhost改为 ip 重新生成war包 war上传到linux的tomcat的webapps下 其他环境配置和macOS大差不差 Tomcat安装使用与部署Web项目的三种方法_tomcat部署web项目-CSDN博客...

MagicLens:新一代图像搜索技术和产品形态

MagicLens&#xff1a;Self-Supervised Image Retrieval with Open-Ended Instructions MagicLens: 自监督图像检索与开放式指令 作者&#xff1a;Kai Zhang&#xff0c; Yi Luan&#xff0c; Hexiang Hu&#xff0c; Kenton Lee&#xff0c; Siyuan Qiao&#xff0c; Wenhu …...

[9] CUDA性能测量与错误处理

CUDA性能测量与错误处理 讨论如何通过CUDA事件来测量它的性能如何通过CUDA代码进行调试 1.测量CUDA程序的性能 1.1 CUDA事件 CPU端的计时器可能无法给出正确的内核执行时间CUDA事件等于是在你的CUDA应用运行的特定时刻被记录的时间戳&#xff0c;通过使用CUDA事件API&#…...

Java学习四

Random 随机数 数组 静态初始化数组 数组在计算机中的基本原理 数组的访问 什么是遍历 数组的动态初始化 动态初始化数组元素默认值规则 Java内存分配介绍 数组在计算机中的执行原理 使用数组时常见的一个问题 案例求数组元素最大值 public class Test1 {public static void ma…...

Vue 父组件使用refs来直接访问和修改子组件的属性或调用子组件的方法

步骤 1: 在子组件中定义要被修改的属性或方法 首先&#xff0c;在子组件中定义你想要父组件能够修改或调用的属性或方法。例如&#xff0c;我们有一个名为MyChildComponent的子组件&#xff0c;它有一个名为childData的数据属性和一个名为updateData的方法。 // 子组件 MyChi…...

范罗士、希喂、安德迈爆款宠物空气净化器哪款好?深度对比测评

作为一名深受养猫过敏困扰的铲屎官&#xff0c;我经常提醒新手铲屎官重视家里的空气环境。宠物的浮毛和皮屑不仅会引发过敏&#xff0c;还可能传播细菌和病毒。很多人以为普通空气净化器能解决问题&#xff0c;但这些产品并未针对宠物家庭的特殊需求。经过多次研究和测试&#…...

SAP OBYC自动记账 详解

在MM模块的许多操作都能实现在FI模块自动过账,如PO收货、发票验证、工单发料、向生产车间发料等等。不用说,一定需要在IMG中进行配置才可以实现自动处理。但SAP实现的这种自动配置的机制是怎样的呢?其实也并不复杂,让我们先以一种最简单的情况来了解实现原理和实现流程,然…...

《NoSQL数据库技术与应用》 MongoDB副本集

《NoSQL数据库技术与应用》 教学设计 课程名称&#xff1a;NoSQL数据库技术与应用 授课年级&#xff1a; 20xx年级 授课学期&#xff1a; 20xx学年第一学期 教师姓名&#xff1a; 某某老师 2020年5月6日 课题 名称 第4章 MongoDB副本集 计划学时 8课时 内容 分析 独立模式可…...

Flutter 中的 DropdownButtonFormField 小部件:全面指南

Flutter 中的 DropdownButtonFormField 小部件&#xff1a;全面指南 在Flutter中&#xff0c;DropdownButtonFormField是一个特殊的表单字段小部件&#xff0c;它结合了下拉选择框&#xff08;DropdownButton&#xff09;和表单字段&#xff08;FormField&#xff09;的功能。…...

哈希算法教程(个人总结版)

背景 哈希算法&#xff08;Hash Algorithm&#xff09;是一种将任意长度的输入&#xff08;也称为消息&#xff09;转换为固定长度的输出&#xff08;也称为哈希值、散列值、摘要&#xff09;的算法。哈希算法在计算机科学中有着广泛的应用&#xff0c;包括数据存储、数据检索…...

Nocobase快速上手 -第一个collection

本文记录Nocobase中如何创建collection&#xff0c;以及如何将collection展示到页面中&#xff0c;并且配置CRUD相应的操作. Collection 在NocoBase中&#xff0c;collection&#xff08;集合&#xff09;是用来组织和存储各种数据的容器&#xff0c;如订单、产品、用户、评论…...

吴恩达2022机器学习专项课程C2W2:2.19 sigmoid函数的替代方案 2.20如何选择激活函数 2.21 激活函数的重要性

这里写目录标题 引言sigmoid激活函数的局限1.回顾需求案例2.ReLU激活函数 常用的激活函数1.线性激活函数的解释 如何选择激活函数&#xff1f;1.选择输出层的激活函数2.选择隐藏层的激活函数 选择激活函数的总结1.输出层总结2.隐藏层总结3.TensorFlow设置激活函数 激活函数多样…...

循序渐进Docker Compose

文章目录 1.概述1.1 Docker Compose 定义1.2 Docker Compose背景1.3 Docker Compose核心概念 2.安装2.1 Official Repos2.2 Manual Installation2.3 v1.x 兼容性 3. YAML 配置说明3.1 Services3.2 Volumes & Networks 4. 解析 Service4.1 Pulling一个Image4.2 Building一个…...

怎样查看JavaScript中没有输出结果的数组值?

在JavaScript中&#xff0c;可以方便地定义和使用数组&#xff0c;对于已经定义的数组&#xff0c;怎样查看其值呢&#xff1f; 看下面的示例&#xff0c;并运行它。 上面的示例中&#xff0c;标签不完整&#xff0c;请补充完整再试运行。你知道少了什么标签么&#xff1f; 注…...

强化学习学习笔记-李宏毅

Policy Gradient actorenvreward function&#xff0c;env和reward是不能控制的&#xff0c;唯一可以变的是actor&#xff0c;Policy π \pi π是一个网络&#xff0c;参数为 θ \theta θ&#xff0c;输入是当前的观察&#xff0c;输出是采取的行为&#xff0c;例如游戏中输…...

吴恩达深度学习笔记:超 参 数 调 试 、 Batch 正 则 化 和 程 序 框 架(Hyperparameter tuning)3.8-3.9

目录 第二门课: 改善深层神经网络&#xff1a;超参数调试、正 则 化 以 及 优 化 (Improving Deep Neural Networks:Hyperparameter tuning, Regularization and Optimization)第三周&#xff1a; 超 参 数 调 试 、 Batch 正 则 化 和 程 序 框 架&#xff08;Hyperparameter …...

SQL 语言:数据控制

文章目录 概述授权&#xff08;GRANT)销权&#xff08;REVOKE&#xff09;总结 概述 SQL语言中的数据控制权限分配是数据库管理的重要组成部分&#xff0c;它涉及到如何合理地为用户分配对数据库资源的访问和使用权限。 权限类型&#xff1a;在SQL中&#xff0c;权限主要分为…...

Voron 2.4 3D打印机进阶调试与故障排除指南

Voron 2.4 3D打印机进阶调试与故障排除指南 【免费下载链接】Voron-2 Voron 2 CoreXY 3D Printer design 项目地址: https://gitcode.com/gh_mirrors/vo/Voron-2 机械系统精调&#xff1a;从结构应力到运动精度 问题导向&#xff1a;框架组装后出现对角线偏差超过2mm&a…...

从一篇TIE论文的稳定性分析入手,手把手复现Bode图判据的MATLAB实现

从TIE论文案例到MATLAB实践&#xff1a;Bode图判据的稳定性分析全解析 在电力电子系统设计中&#xff0c;LCL型并网逆变器的稳定性分析一直是工程师面临的挑战。2015年发表在IEEE Transactions on Industrial Electronics上的那篇经典论文&#xff0c;为我们提供了一个绝佳的研…...

影墨·今颜GPU算力适配:RTX 4090单卡实测每秒1.8张1024x1536图

影墨今颜GPU算力适配&#xff1a;RTX 4090单卡实测每秒1.8张1024x1536图 1. 引言&#xff1a;当顶级AI影像遇上顶级显卡 如果你是一位内容创作者&#xff0c;或者对AI生成人像有浓厚兴趣&#xff0c;那么“影墨今颜”这个名字最近可能已经进入了你的视野。它被描述为一款融合…...

Phi-3-Mini-128K实战JavaScript:构建前端智能代码提示插件

Phi-3-Mini-128K实战JavaScript&#xff1a;构建前端智能代码提示插件 最近在折腾前端项目时&#xff0c;我总在想&#xff0c;要是写代码时能有个更懂我的助手就好了。现有的代码补全工具虽然不错&#xff0c;但很多时候还是停留在语法层面&#xff0c;对于业务逻辑、复杂函数…...

HDSceneColor节点]原理解析与实际应用

渲染管线兼容性详解HD Scene Color节点的可用性完全取决于所使用的渲染管线&#xff0c;这是开发者在选择和使用该节点时必须首先考虑的因素。高清渲染管线&#xff08;HDRP&#xff09;支持HDRP是Unity针对高端平台和高端硬件设计的高保真渲染解决方案HD Scene Color节点专为H…...

Vivado项目文件太多分不清?这份FPGA开发必备的‘文件后缀速查手册’请收好

Vivado项目文件管理终极指南&#xff1a;从后缀识别到高效工作流 当你第一次打开一个成熟的Vivado项目文件夹时&#xff0c;那种面对几十种陌生文件后缀的茫然感&#xff0c;相信每个FPGA开发者都记忆犹新。就像走进了一个满是神秘符号的仓库&#xff0c;每个文件似乎都在向你发…...

Ostrakon-VL终端入门指南:如何导出结构化JSON结果用于BI工具接入

Ostrakon-VL终端入门指南&#xff1a;如何导出结构化JSON结果用于BI工具接入 1. 认识Ostrakon-VL终端 Ostrakon-VL终端是一款专为零售与餐饮行业设计的智能图像识别工具&#xff0c;它将复杂的AI技术包装成一个充满游戏感的像素风格界面。这个终端基于Ostrakon-VL-8B多模态大…...

SpringBoot+Redis实现高并发短信登录:双拦截器设计背后的架构思考

SpringBootRedis高并发短信登录架构深度解析&#xff1a;双拦截器设计与性能优化实战 1. 高并发场景下的登录架构挑战 在当今互联网应用中&#xff0c;短信验证码登录已成为主流的身份验证方式之一。但当系统面临高并发请求时&#xff0c;传统的Session-based方案会暴露出诸多瓶…...

CTFshow Misc挑战:从WinRAR到明文攻击的实战解析

1. 初识CTFshow Misc挑战&#xff1a;压缩包破解的奥秘 第一次接触CTFshow的Misc题目时&#xff0c;我被那个看似普通的压缩包难住了整整两天。那是个名为6.zip的文件&#xff0c;用360解压提示需要密码&#xff0c;这种场景在CTF比赛中实在太常见了。很多新手遇到这种情况会直…...

工具调用准确率飙到95%!Qwen-7B解耦微调实战实录(非常详细),大模型调优从入门到精通,收藏这一篇就够了!

用Qwen-7B做Agent&#xff0c;本来信心满满&#xff0c;结果MCP一跑&#xff0c;选工具选不对、参数填得稀巴烂&#xff0c;准确率惨不忍睹&#xff0c;最高也就60%徘徊。 后来我发现&#xff1a;普通LoRA根本救不了复杂工具调用。 真正能救命的&#xff0c;是2026年最火的解…...