动态内存管理—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+1
	pc->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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/655799.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

上周暗网0day售卖情报一览

黑客声称以 1,700,000 美元出售 Outlook RCE 漏洞 0Day 令人担忧的是&#xff0c;一个名为“Cvsp”的威胁参与者宣布出售所谓的 Outlook 远程代码执行 (RCE) 漏洞 0day。这一所谓的漏洞旨在针对跨 x86 和 x64 架构的各种 Microsoft Office 版本&#xff0c;对全球用户构成重大安…

Git-01

Git是一个免费且开源的分布式版本控制系统&#xff0c;它可以跟踪文件的修改、记录变更的历史&#xff0c;并且在多人协作开发中提供了强大的工具和功能。 Git最初是由Linus Torvalds开发的&#xff0c;用于Linux内核的开发&#xff0c;现在已经成为了广泛使用的版本控制系统&a…

【Spring】深入学习AOP编程思想的实现原理和优势

【切面编程】深入学习AOP编程思想的实现原理和优势 前言AOP的由来及AOP与代理的关系AOP的实现方式详解静态代理动态代理 AOP的应用场景记录日志权限控制数据库事务控制缓存处理异常处理监控管理 AOP的底层实现全流程解析Spring AOP的简介动态代理的实现原理Spring AOP的实现原理…

U-Net网络

U-Net网络 一、基本架构 各个箭头的解释&#xff1a; conv 3 * 3, ReLU&#xff1a;表示通过一个3 * 3的卷积层&#xff0c;并且该层自动附带一个非线性激活层&#xff08;ReLu&#xff09;copy and crop&#xff1a;表示进行裁剪然后再进行拼接&#xff08;在channel的维度上…

仿真51单片机程序(下载安装+Proteus)

我是看的这个大佬的:http://t.csdnimg.cn/Z07SZ 大佬写的很详细了,我就不献丑了. 贴上俩个运行成功的截图,有碰到问题的欢迎交流.

四川景源畅信:新人做抖店的成本很高吗?

随着社交媒体的兴起&#xff0c;抖音成为了一个新兴的电商平台——抖店。不少创业者和商家看中了其庞大的用户基础&#xff0c;想要通过开设抖店来拓展销路。然而&#xff0c;对于刚入行的新手来说&#xff0c;成本问题总是让人犹豫不决。究竟新人做抖店的成本高不高?本文将围…

学习笔记——STM32F103的V3版本——3*3矩阵键盘控制数码管

一.硬件 1.数码管 2.3*3的矩阵键盘&#xff08;自己做的模块&#xff08;手残党一枚&#xff09;&#xff09; 3.总体连接 二.在Keil5中的部分软代码 test.c中&#xff1a; #include "sys.h" #include "usart.h" #include "delay.h" #include …

【NumPy】全面解析NumPy的bitwise_xor函数:高效按位异或操作指南

&#x1f9d1; 博主简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

【实战JVM】-基础篇-04-自动垃圾回收

【实战JVM】-基础篇-04-自动垃圾回收 自动垃圾回收1 多语言内存管理1.1 C/C的内存管理1.2 Java的内存管理1.3 自动与手动对比1.4 应用场景 2 方法区的回收2.1 回收条件 3 堆回收3.1 判断是否被引用3.1.1 引用计数法3.1.2 可达性分析算法3.1.2.1 GC Root3.1.2.2 监视GC Root3.1.…

如何用分立器件设计一个过流保护电路

过流保护电路是指当后级负载电流过大或者发生短路时&#xff0c;自动切断电源与后级负载&#xff0c;从而防止大电流损害电源电路&#xff0c;过流保护又叫OCP。 常见的过流保护电路有保险丝过流保护&#xff0c;集成的过流保护芯片&#xff0c;还有这种分立器件搭建的过流保护…

检索模型预训练方法:RetroMAE

论文title&#xff1a;https://arxiv.org/pdf/2205.12035RetroMAE: Pre-Training Retrieval-oriented Language Models Via Masked Auto-Encoder 论文链接&#xff1a;https://arxiv.org/pdf/2205.12035 摘要 1.一种新的MAE工作流&#xff0c;编码器和解器输入进行了不同的掩…

React@16.x(12)ref 转发-forwardRef

目录 1&#xff0c;介绍2&#xff0c;类组件如何使用4&#xff0c;应用场景-高阶组件HOC 1&#xff0c;介绍 上篇文章中提到&#xff0c;ref 只能对类组件使用&#xff0c;不能对函数组件使用。 而 ref 转发可以对函数组件实现类似的功能。 使用举例&#xff1a; import Re…

SCI一区 | Matlab实现PSO-TCN-LSTM-Attention粒子群算法优化时间卷积长短期记忆神经网络融合注意力机制多变量时间序列预测

SCI一区 | Matlab实现PSO-TCN-LSTM-Attention粒子群算法优化时间卷积长短期记忆神经网络融合注意力机制多变量时间序列预测 目录 SCI一区 | Matlab实现PSO-TCN-LSTM-Attention粒子群算法优化时间卷积长短期记忆神经网络融合注意力机制多变量时间序列预测预测效果基本介绍程序设…

【CCF-CSP】202309-1 202309-2 坐标变换

坐标变换&#xff08;其一&#xff09; 代码&#xff1a; #include <bits/stdc.h> using namespace std; int main(){int n,m,x,y,sumx0,sumy0;cin>>n>>m;for(int i1;i<n;i){cin>>x>>y;sumxx,sumyy;}for(int i1;i<m;i){cin>>x>&…

用天工AI写文章,节约了8个人的成本

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 当下AI工具最大的问题是什么? 是写的文章没有灵魂、没有感情、像机器人! 生成的文章官话连篇&#xff0c;人们一眼就看出是AI写的&#xff0c;这种文章怎么能给客户交差呢?自己这关都过不去&#xff0c;是吧? …

md5强弱碰撞

一&#xff0c;类型。 1.弱比较 php中的""和""在进行比较时&#xff0c;数字和字符串比较或者涉及到数字内容的字符串&#xff0c;则字符串会被转换为数值并且比较按照数值来进行。按照此理&#xff0c;我们可以上传md5编码后是0e的字符串&#xff0c;在…

四川汇聚荣聚荣科技有限公司好不好?

在当今科技飞速发展的时代&#xff0c;企业要想在激烈的市场竞争中脱颖而出&#xff0c;必须具备强大的技术实力和良好的市场口碑。那么&#xff0c;作为一家专注于科技创新的公司&#xff0c;四川汇聚荣聚荣科技有限公司究竟如何呢?接下来&#xff0c;我们将从四个方面进行详…

K210 数字识别 教程

一、烧写固件 连接k210开发板&#xff0c;点开烧录固件工具&#xff0c;选中固件&#xff0c;并下载 二、模型训练 网站&#xff1a;MaixHub 1、上传文件 2、开始标记数据 添加9个标签&#xff0c;命名为1~9&#xff0c;按键盘w开始标记&#xff0c;键盘D可以下一张图片&…

YashanDB携手慧点科技完成产品兼容认证 助力国产信创生态建设

近日&#xff0c;深圳计算科学研究院崖山数据库系统YashanDB与慧点科技顺利完成兼容性互认证。经严格测试&#xff0c;双方产品完全兼容&#xff0c;稳定运行&#xff0c;共同支撑政府、企业、金融等办公应用场景下的数字化转型升级&#xff0c;为企业的信息技术应用创新提供坚…

C++容器之位集(std::bitset)

目录 1 概述2 使用实例3 接口使用3.1 constructor3.2 count_and_size3.3 test3.4 any3.5 none3.6 all3.7 set3.8 reset3.9 filp3.10 to_string3.11 to_ulong3.12 to_ullong3.13 operators1 概述 位集存储位(只有两个可能值的元素:0或1,true或false,…)。   该类模拟bool…