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

龙海建设局网站濮阳市城乡一体化示范区

龙海建设局网站,濮阳市城乡一体化示范区,邯郸市住房和建设官方网站,广州越秀区发布Hi~!这里是奋斗的小羊,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~ 💥💥个人主页:奋斗的小羊 💥💥所属专栏:C语言 🚀本系列文章为个人学习…

Hi~!这里是奋斗的小羊,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~
💥💥个人主页:奋斗的小羊
💥💥所属专栏:C语言

🚀本系列文章为个人学习笔记,在这里撰写成文一为巩固知识,二为展示我的学习过程及理解。文笔、排版拙劣,望见谅。


目录

  • 前言
  • 1、为什么要有动态内存分配
  • 2、malloc 和 free
    • 2.1 malloc
    • 2.2 free
  • 3、calloc 和 realloc
    • 3.1 calloc
    • 3.2 realloc
  • 总结

前言

本篇文章将介绍C语言中除指针和结构体外又一重要的内容——动态内存管理
在C语言中,我们更多的需要手动分配和释放内存,这意味着我们必须正确地管理内存,以避免内存泄漏、内存溢出和其他内存错误,这些错误可能导致程序崩溃或安全漏洞。因此,了解内存管理是编写高质量、高效率和健壮性程序的重要部分。


1、为什么要有动态内存分配

目前我们申请内存的方法有两种,创建相关类型变量int n = 0;和创建相关类型数组int arr[10] = { 0 };
但是这样申请的内存是有缺点的:

  • 申请的内存大小是有限的,不能指定大小

  • 数组在声明的时候必须指定长度,数组空间一旦确定下来就不能调整

  • 数组空间在申请前我们不能给出一个准确的大小,大了浪费,小了不够

有时候我们需要的空间大小在程序运行的时候才能知道,那数组的编译时开辟空间的方式就不能满足了
为了解决这个问题,C语言引入了动态内存开辟,让我们可以自己申请和释放内存,这样就比较灵活了
空间不够我们可以增大,空间太大我们可以缩小


2、malloc 和 free

使用动态内存管理函数都需要包含头文件<stdlib.h>

2.1 malloc

C语言提供了一个动态内存开辟的函数malloc

void* malloc(size_t size);

malloc 函数的作用是开辟一块指定大小的、连续的、有限的内存空间,大小由size 决定,是不能开辟无限空间的
在x86环境下开辟一块超大内存空间,若开辟失败打印出失败原因:

#include <stdio.h>
#include <stdlib.h>int main()
{int* p = (int*)malloc(INT_MAX);//INT_MAX=2147483647if (p == NULL){//空间开辟失败perror("malloc");//失败后用return终止程序return 1;}return 0;
}

在这里插入图片描述

对于malloc函数,我们需要注意:

  • 参数的单位是字节
  • 如果size是0,malloc的行为是未定义的,取决于编译器
  • malloc的返回值是void *类型的指针
  • 申请空间成功的话返回起始地址,反之则返回NULL
  • malloc返回的地址我们基本都会直接强转为我们需要的类型的地址

示例:申请10个整形空间,存入1~10

#include <stdio.h>
#include <stdlib.h>int main()
{int* p = (int*)malloc(10 * sizeof(int));if (p == NULL){//空间开辟失败perror("malloc");//失败后用return终止程序return 1;}//可以使用开辟好的空间int i = 0;for (i = 0; i < 10; i++){*(p + i) = i + 1;}return 0;
}

在这里插入图片描述

malloc申请的空间和数组有什么区别?

  • 动态内存的大小可以调整
  • 空间开辟的位置不一样

在这里插入图片描述
我们创建的局部数组就在栈区

虽然空间有区别,但在使用上是一样的


2.2 free

C语言提供了另外一个函数free,专门是用来做动态内存的释放和回收的,mallocfree基本都要成对存在,函数原型如下:

void free(void* ptr);

free函数是用来释放开辟的动态内存的,我们将上面开辟的动态内存释放:

#include <stdio.h>
#include <stdlib.h>int main()
{int* p = (int*)malloc(10 * sizeof(int));if (p == NULL){//空间开辟失败perror("malloc");//失败后用return终止程序return 1;}//可以使用开辟好的空间int i = 0;for (i = 0; i < 10; i++){*(p + i) = i + 1;}//将开辟的动态内存释放free(p);p = NULL;return 0;
}

注意:用free释放动态内存空间后,指针p中还保留着其地址,安全起见我们需要给指针p赋NULL,因此free(p)p = NULL总是一起出现的
既然有free函数,所以说明动态内存是不能自动回收的,所以malloc申请的空间和数组又有了一个区别:

数组在进它的作用域时申请空间,出作用域时自动释放空间;而malloc申请的动态内存空间需要我们手动地释放
如果不释放,程序结束的时候也会被系统自动回收,但是并不建议这样做,自己申请的空间要自己释放,不然会浪费资源,也是不负责任的行为

特别的:

  • 如果参数ptr指向的空间不是动态开辟的,free的行为是未定义的
  • 如果参数ptrNULL指针,则free什么都不做

3、calloc 和 realloc

3.1 calloc

C语言还提供了一个函数calloc,其函数原型是:

void* calloc( size_t num, size_t size );

calloc的作用是开辟num个大小为size的连续空间,同时将内存空间初始化为0

calloc申请10个整型的空间,并打印出内存中的值

#include <stdio.h>
#include <stdlib.h>int main()
{//int* p = (int*)malloc(10 * sizeof(int));int* p = (int*)calloc(10, sizeof(int));if (p == NULL){//空间开辟失败perror("calloc");//失败后用return终止程序return 1;}//可以使用开辟好的空间int i = 0;for (i = 0; i < 10; i++){printf("%d ", p[i]);//*(p + i)}//将开辟的动态内存释放free(p);p = NULL;return 0;
}

在这里插入图片描述

如果将malloc申请的动态内存空间中的值打印出来,应该都是随机值:

在这里插入图片描述

所以malloccalloc只两个区别:

  • malloc有1个参数,而calloc有2个参数
  • calloc会把申请的动态内存空间内的值初始化为全0,而malloc不会

3.2 realloc

在文章开头我们提到了,有时在定义数组的时候我们并不能给定数组一个准确的长度,大了浪费,小了不够。
realloc函数的出现让动态内存管理更加灵活,它的作用是调整动态内存空间的大小,原型如下:

void *realloc( void *ptr, size_t new_size );
  • ptr:指向之前通过malloccallocrealloc开辟的内存块(必须是起始地址)
  • new_size:内存新大小(单位字节)
  • 返回值void *:调整后的内存起始地址,若失败则返回空指针

当我们想用realloc函数将一个动态内存空间调整的小一点,则相应的动态内存空间就会减小到我们想要的大小;而当我们想用realloc函数将一个动态内存空间调整的大一点,这时候就会有两种情况出现:

情况一:原内存后的可用空间足够我们的扩容
在这里插入图片描述

这时候realloc函数就会按正常程序走,返回原内存的起始地址

情况二:原内存后的可用空间不够我们扩容
在这里插入图片描述

这时候realloc函数会在堆区中找一块足以完成我们目的的内存空间,并将原内存中的内容拷贝到新内存空间中,realloc函数还会自己将原内存空间释放,最后返回新开辟的内存空间的起始地址

当然,不管我们是想将原内存空间调小还是扩容,都有失败的可能
所以,realloc函数的返回值我们不能直接用指向原内存的指针接收,因为如果realloc返回的是NULL,则原内存的地址都会消失
我们可以用一个新指针过渡

#include <stdio.h>
#include <stdlib.h>int main()
{//int* p = (int*)malloc(10 * sizeof(int));int* p = (int*)calloc(10, sizeof(int));if (p == NULL){//空间开辟失败perror("calloc");//失败后用return终止程序return 1;}//可以使用开辟好的空间int i = 0;for (i = 0; i < 10; i++){printf("%d ", p[i]);//*(p + i)}//调整空间,扩容到20个整型空间int* ptr = (int*)realloc(p, 20 * sizeof(int));//用新指针过渡if (ptr != NULL){p = ptr;}//使用// ...//将开辟的动态内存释放free(p);p = NULL;return 0;
}

总结

  • 动态内存管理通过使用malloccallocrealloc等函数来分配内存,使用free函数来释放已经分配的内存。
  • 动态内存管理能够优化程序的内存利用率,避免内存泄漏和内存溢出等问题,在C语言中,动态内存管理是我们必须掌握的重要技能之一
http://www.yayakq.cn/news/416317/

相关文章:

  • 传统文化网站设计深圳网站开发怎么样
  • 欧赛网站建设自己名字怎么设计logo
  • 地方文明网站建设措施wordpress如何修改上传图片大小
  • 伪类网站好看的网站后台界面
  • wordpress音乐插件mp3全能优化型网站
  • 如何网站制作wordpress标签没反应
  • 国家重大建设项目库网站装修公司网站建设的意义
  • 做爰全过程的视频网站潍坊网站建设策划
  • 有个网站经常换域名哪里有零基础网站建设教学服务
  • 网站开发项目介绍网站建设腾讯云
  • 商会网站建设招标方案建设银行如何设置网站查询密码
  • 乐温州网站建设上海高端品牌网站建设专家
  • 免费视频推广的软件有哪些邯郸网站优化怎么做
  • 聊城网站改版信誉好的商城网站建设
  • 网站可信度建设苏州风光ix5
  • 昆山网站建设哪家便宜铜陵app网站做招聘信息
  • 网站建设合同的法律用自己网站做邮箱域名解析
  • 个人作品展示 网站ui设计培训是什么
  • 友创互联网站建设有限公司企业小程序制作开发
  • 江苏省城乡建设厅建设网站wordpress 修改源码
  • 广州建筑集团网站营销型企业网站怎么建站
  • 心理医院网站优化服务商wordpress放nas
  • o2o网站wordpress 删除google
  • 网站服务器租赁合同企业网站登录入口官网
  • 浏览国外服务器的网站wordpress 字段插件
  • 现在还有企业要建网站吗长沙百姓网
  • 长春火车站到龙嘉机场高铁时刻表网站页面布局图片
  • 网页设计与制作个人网站安阳市设计
  • 罗湖公司网站建设玉环在哪里做网站
  • 专门做库存处理的网站wordpress视频博客