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

C语言复习--动态内存管理

        下面我们来看C语言中的动态内存管理,在之后的数据结构中会运用到C语言中的指针,结构体和动态内存管理,所以这部分还是比较重要的.下面进入正题.

为什么要有动态内存分配

        但是上面的两种方式开辟的内存的大小都是固定的.数组也是,在数组开辟之前一定要确定好数组大小,并且数组开辟后空间大小不能被改变.

        有时候我们需要的空间⼤⼩在程序运⾏的时候才能知道,那数组的编译时开辟空间的⽅式就不能满⾜了.C语⾔引⼊了动态内存开辟,让程序员⾃⼰可以申请和释放空间,这种方式这就比较灵活了.

        下面我们就来看下动态内存分配的有关函数吧.

malloc和free

  malloc

        和之前复习一样我们先来看他的函数原型

void* malloc (size_t size);

  free

         C语⾔提供了另外⼀个函数free,专⻔是⽤来做动态内存的释放和回收的,函数原型见下

void free (void* ptr);

        这两个函数都在头文件stdlib.h中.下面举个小例子

int main()
{int* ptr = (int*)malloc(sizeof(int) * 10);if (ptr == NULL){perror("malloc");return -1;}for (int i = 0; i < 10; i++){*(ptr + i) = i;}for (int i = 0; i < 10; i++){printf("%d ", *(ptr + i));}printf("\n");//一定不要忘记释放内存,否则会内存泄漏free(ptr);//释放后要及时置空//free无法置空传入指针,因为free是传值调用ptr = NULL;return 0;
}

calloc和realloc

  calloc

        calloc也是C语言提供的用于动态内存的分配的函数.下面让我们看下他的函数原型吧

void* calloc (size_t num, size_t size);

        1.函数的功能是为 num 个大小为 size 的元素开辟⼀块空间,并且把空间的每个字节初始化为0.

(只能初始化为0,不可以指定初始化内容,不要与memset搞混了如果区分不开可以看下

        C语言复习笔记--内存函数-CSDN博客)

        2.与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全 0。

        例子见下

int main()
{int* ptr = (int*)calloc(10, sizeof(int));if (ptr == NULL){perror("malloc");return -1;}//没有进行赋值直接打印for (int i = 0; i < 10; i++){printf("%d ", *(ptr + i));}printf("\n");//一定不要忘记释放内存,否则会内存泄漏free(ptr);//释放后要及时置空//free无法置空传入指针,因为free是传值调用ptr = NULL;return 0;
}

        输出结果

  realloc

        函数原型见下

void* realloc (void* ptr, size_t size);

ptr 是要调整的内存地址

size 调整之后新大小

        函数作用:

         情况2时,函数会做找到新空间开辟,赋值原空间的值到新空间,释放原空间,然后返回新空间的地址这几件事情. 

        realloc使用例子

int main()
{int* ptr = (int*)malloc(sizeof(int) * 10);if (ptr == NULL){perror("malloc");return -1;}for (int i = 0; i < 10; i++){*(ptr + i) = i;}for (int i = 0; i < 10; i++){printf("%d ", *(ptr + i));}printf("\n");//空间不够了想扩容int* tmp = (int*)realloc(ptr, sizeof(int) * 15);//不能直接给tmp,因为扩容失败返回空指针,直接给的话连之前的空间都找不到了,会发生内存泄露if (NULL == tmp){perror("realloc");return -1;}ptr = tmp;for (int i = 10; i < 15; i++){*(ptr + i) = i;}for (int i = 0; i < 15; i++){printf("%d ", *(ptr + i));}printf("\n");//一定不要忘记释放内存,否则会内存泄漏free(ptr);//释放后要及时置空//free无法置空传入指针,因为free是传值调用ptr = NULL;return 0;
}

        输出结果

常见的动态内存的错误

        要对开辟出来的动态内存进行一下检查.

        尽量不要让接收动态开辟内存函数返回的指针进行自加自减运算.

        释放后记得将指针制空.

        忘记释放不再使⽤的动态开辟的空间会造成内存泄漏。

        切记:动态开辟的空间⼀定要释放,并且正确释放。

        以上就是动态内存分配的基本知识,还有和这里相关的一个小语法柔性数组,想要了解一下可以看这篇博客C语言复习--柔性-CSDN博客.

        我们下篇博客见.

http://www.xdnf.cn/news/380377.html

相关文章:

  • 同步、异步、并发的区别
  • Python与YOLO:自动驾驶中的实时物体检测
  • comfyui 如何优雅的从Hugging Face 下载模型,文件夹
  • 2025年特种作业操作证考试题库及答案(登高架设作业)
  • AST(抽象语法树)与 HBO(基于历史的优化)详解
  • 使用 Jackson 在 Java 中解析和生成 JSON
  • Spring事务管理实现机制
  • Windows右键管理工具:轻松添加/删除/修改右键菜单项!
  • xml与注解的区别
  • 机器学习 day01
  • 如何更改typora图片存储位置
  • 将一张100 元的钞票换成1 元、2元、5 元和10 元的零钱,每种零钞至少一张
  • CH579 CH573 CH582 CH592 蓝牙主机(Central)实例应用讲解
  • C. scanf 函数基础
  • Linux--JsonCpp
  • 【C++】内存管理
  • Lettuce 节点刷新、连接优化与 Spring 升级适配全解析:从环境约束到生产验证
  • printf调试时候正常,运行时打印不出来
  • spring响应式编程系列:异步消费数据
  • springboot3+vue3融合项目实战-大事件文章管理系统-更新用户信息
  • MGP-STR:用于场景文本识别的多粒度预测
  • 【Vulkan 入门系列】创建和配置描述符集,创建同步对象(九)
  • 跟我学C++中级篇——STL中的删除对比
  • C++ learning day 02
  • 常见的算法介绍
  • 人脸真假检测:SVM 与 ResNet18 的实战对比
  • Java单例模式总结
  • 【Linux 系统调试】系统内存越界调试利器Electric Fence详解
  • waterfall与Bidding的请求机制
  • Day20打卡-奇异值SVD分解