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

十个程序员必备的网站凡科网站建设

十个程序员必备的网站,凡科网站建设,凡科快图网页版,宿迁沭阳疫情最新消息文章目录 一、动态内存函数1. malloc2. calloc3. realloc4. free 二、常见的错误1.malloc或calloc开辟的空间未检查2.越界访问3.对非malloc和calloc开辟的空间,用free释放4.对同一块动态内存多次释放5.用free释放动态内存的一部分 三、通讯录(动态版本改写)总结 一、…

在这里插入图片描述

文章目录

  • 一、动态内存函数
    • 1. malloc
    • 2. calloc
    • 3. realloc
    • 4. free
  • 二、常见的错误
    • 1.malloc或calloc开辟的空间未检查
    • 2.越界访问
    • 3.对非malloc和calloc开辟的空间,用free释放
    • 4.对同一块动态内存多次释放
    • 5.用free释放动态内存的一部分
  • 三、通讯录(动态版本改写)
  • 总结


一、动态内存函数

要介绍动态内存函数,我们就要知道动态内存函数开辟的空间在内存的什么位置。
如下图所示:
动态内存函数开辟的空间在堆区
动态内存函数开辟的空间在堆区,该区域的空间,只有free函数和程序结束才会释放。

1. malloc

函数的声明:void* malloc (size_t size);包含在<stdlib.h>头文件中。
调用该函数可以向内存中申请大小为size个字节的连续空间,并返回该空间的起始地址。
注意:

  • 如果malloc开辟空间成功,则返回成功开辟好空间的起始地址
  • 如果malloc开辟空间失败,则返回NULL
  • 不要开辟大小为0的空间,这是标准未定义的。

因此,malloc开辟空间后,我们要检查返回值。

#include <stdio.h>
#include <stdlib.h>int main()
{int* pa = (int*)malloc(sizeof(int) * 10);//开辟大小为40个字节的空间//检查是否空间开辟失败if (pa == NULL){exit(-1);}free(pa);pa = NULL;return 0;
}

2. calloc

函数的声明:void* calloc (size_t num, size_t size);包含在<stdlib.h>头文件中。
调用该函数可以向内存中申请num个大小是size个字节的连续空间,再将空间每一个字节初始化为0,并返回该空间的起始地址。
calloc与malloc的唯一区别在于,calloc会将空间每一个字节初始化为0。
如下所示:

#include <stdio.h>
#include <stdlib.h>int main()
{int* arr1 = (int*)malloc(sizeof(int) * 10);if (arr1 == NULL){exit(-1);}for (int i = 0; i < 10; i++){printf("%d ", arr1[i]);}printf("\n");int* arr2 = (int*)calloc(sizeof(int), 10);if (arr2 == NULL){exit(-1);}for (int i = 0; i < 10; i++){printf("%d ", arr2[i]);}free(arr1);free(arr2);arr1 = NULL;arr2 = NULL;return 0;
}

在这里插入图片描述

3. realloc

函数的声明:void* realloc (void* ptr, size_t size);包含在<stdlib.h>头文件中。
调用该函数可以调整由malloc和calloc开辟的空间大小,调整为size个字节大小的空间。
但要注意,其调整空间大小的方式有两种,原地扩容和异地扩容。

  • 原地扩容,原地址空间后空间大小充足,在原地址空间直接扩容。

  • 异地扩容,原地址空间后空间大小不够,在堆区另找一片充足的空间使用。

  • 如果调整的大小过大,realloc会返回NULL。

//异地扩容
int main()
{int* pa = (int*)malloc(sizeof(int) * 10);if (pa == NULL){exit(-1);}printf("%p\n", pa);int* tmp = (int*)realloc(pa, sizeof(int) * 20);if (tmp != NULL){pa = tmp;printf("%p\n", pa);}free(pa);pa = NULL;return 0;
}

在这里插入图片描述


//原地扩容
int main()
{char* pa = (char*)malloc(sizeof(char) * 10);if (pa == NULL){exit(-1);}printf("%p\n", pa);char* tmp = (char*)realloc(pa, sizeof(char) * 20);if (tmp != NULL){pa = tmp;printf("%p\n", pa);}free(pa);pa = NULL;return 0;
}

在这里插入图片描述

4. free

函数的声明:void free (void* ptr);包含在<stdlib.h>头文件中。
调用该函数可以释放由malloc和calloc开辟的空间,指针变量ptr本身内容不变,需要程序员本身置空。

  • 如果ptr是NULL,则函数什么事都不会做
  • 如果ptr并不是malloc和calloc开辟的空间,那free函数的行为未定义

如下:

int main()
{int* pa = (int*)malloc(sizeof(int) * 10);if (pa == NULL){exit(-1);}free(pa);//释放pa所指向的空间pa = NULL;//pa置NULL,防止野指针return 0;
}

二、常见的错误

1.malloc或calloc开辟的空间未检查

有时开辟空间过大,而未检查时,会发生对NULL的解引用


int main()
{int* pa = (int*)malloc(sizeof(int) * INT_MAX);*pa = 10;free(pa);pa = NULL;return 0;
}

在这里插入图片描述

2.越界访问

访问超出开辟空间大小

int main()
{int* pa = (int*)malloc(sizeof(int) * 10);if (pa == NULL){exit(-1);}for (int i = 0; i < 11; i++){pa[i] = 0;}free(pa);pa = NULL;return 0;
}

在这里插入图片描述

3.对非malloc和calloc开辟的空间,用free释放

free函数只能用了释放动态内存空间

int main()
{int arr[10] = { 0 };free(arr);return 0;
}

在这里插入图片描述

4.对同一块动态内存多次释放

动态内存空间释放一次即可

int main()
{int* pa = (int*)malloc(sizeof(int) * 10);if (pa == NULL){exit(-1);}free(pa);free(pa);pa = NULL;return 0;
}

在这里插入图片描述

5.用free释放动态内存的一部分

开辟的动态内存空间实际大小要大于我们申请的大小,那多出的一部分空间要记录我们这次申请空间的信息,free函数就可以根据这一部分信息来释放我们申请的空间大小。如果我们传递的指针并未指向空间首地址,那么free就找不到信息来释放空间。

int main()
{int* pa = (int*)malloc(sizeof(int) * 10);if (pa == NULL){exit(-1);}pa++;free(pa);pa = NULL;return 0;
}

在这里插入图片描述

三、通讯录(动态版本改写)

静态版本通讯录
相对于静态版本而言,动态版本改变并不多也不难,下面就是要改变的部分。

  1. 结构
//动态版本
typedef struct Contact
{PeoInfo* data;int sz;//记录此时已用的大小int capacity;//记录通讯录的大小
}Contact;

2.初始化InitContact

#define INITSIZE 10//初始化通讯录
void InitContact(Contact* pc)
{pc->sz = 0;pc->capacity = INITSIZE;pc->data = (PeoInfo*)malloc(sizeof(PeoInfo) * INITSIZE);if (pc->data == NULL){perror("malloc");return;}
}
  1. 扩容AddCapacity
bool AddCapacity(Contact* pc)
{PeoInfo* tmp = realloc(pc->data, sizeof(PeoInfo) * (pc->capacity) * 2);if (tmp == NULL){perror("realloc");return false;}pc->data = tmp;pc->capacity *= 2;return true;
}//添加联系人
void AddContact(Contact* pc)
{assert(pc);if (pc->sz == pc->capacity){if (AddCapacity(pc) == true){printf("扩容成功\n");}else{printf("扩容失败\n");return;}}printf("请输入联系人名字:>");scanf("%s", pc->data[pc->sz].name);printf("请输入联系人性别:>");scanf("%s", pc->data[pc->sz].sex);printf("请输入联系人年龄:>");scanf("%d", &(pc->data[pc->sz].age));printf("请输入联系人电话:>");scanf("%s", pc->data[pc->sz].tele);printf("请输入联系人地址:>");scanf("%s", pc->data[pc->sz].adder);pc->sz += 1;
}
  1. 退出ExitContact
//退出通讯录
void ExitContact(Contact* pc)
{free(pc->data);pc->data = NULL;pc->sz = 0;pc->capacity = 0;
}

总结

以上就是我对于动态内存管理的了解和应用。

http://www.tj-hxxt.cn/news/97646.html

相关文章:

  • 页面设计制作网站源码北京百度seo排名点击器
  • 网站的ftp怎么查百度收录哪些平台比较好
  • 有做网站吗seo代码优化步骤
  • 网页设计于制作课程标准徐州自动seo
  • 如何查网站建设者ip如何制作网页广告
  • 河北pc端网站开发百度发布
  • 直播软件开发公司南宁百度seo排名价格
  • 自己做网站免费官方百度下载安装
  • 企业建站官网运营朋友圈广告投放
  • 做搜索网站app推广方法及技巧
  • 公司网站建设应注意西安网站建设制作
  • 网站咨询窗口怎么做超级外链工具 增加外链中
  • 美容院网站建设方案书策划网络营销活动
  • 安全可靠网站认证域名备案查询
  • 帝国网站模板建设完成显示不正常seo网络推广机构
  • 网站的建设与维护实践报告谷歌外贸seo
  • 哪里可以找到做网站的成都网站快速排名
  • 花都网站开发公司百度快照官网
  • 免费建域名网站最近一周热点新闻
  • 网站建设长春营销渠道的三个类型
  • 建e网室内设计网免下载费seo快速排名优化公司
  • 无锡网站的建设做网站需要多少钱
  • 城市规划建设网站关键词排名是由什么决定的
  • 做英雄联盟网站的图片素材人力资源培训与开发
  • 深圳网站建设托管百度河南代理商
  • 专业集团网站建设做网络推广
  • 在泰安市有做阿里巴巴网站的攀枝花网站seo
  • 宁波网站设计企业模板建站难吗
  • 陕西网站开发公司地址网络营销推广的渠道有哪些
  • java做网站快不快内容营销策略有哪些