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

C语言基础第18天:动态内存分配

动态内存分配

        要实现动态内存分配,需要使用标准C库提供的库函数,我们所说的动态内存分配,其实就是在堆区申请内存(此时的内存回收需要程序员自身来维护)。

常用函数

malloc

头文件:

#include <stdlib.h>

 函数原型:

void* malloc(size_t size);

功能:分配指定字节数的内存到堆区,返回指向内存块首地址的指针。内存内容未初始化(随机值)

参数:

        size :要分配的内存大小(字节),这里的size_t是数据类型 unsigned long int 的别名。

返回值:

        成功 :返回内存指针(申请到的内存的首地址)。

        失败 :失败返回 NULL。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main()
{// 新建一个指针变量,用来接收内存分配后返回的堆内存首地址int *p = malloc(sizeof(int)); // 4字节 这里尽量不使用常量// 对于指针的使用,一定要进行有效性校验,防止野指针if(p == NULL)// 等价于 !p{perror("内存申请失败!");// 这个函数用于向控制台输出异常信息return -1;}// malloc申请的内存空间,默认填充的是随机值,需要我们手动清零memset(p,0,sizeof(int)); // 对指定空间赋值0,支持批量赋值// 向这块空间赋值*p = 100;// 访问这块空间printf("%d\n", *p);// 堆空间使用完毕,一定要释放内存,此时需要程序员写代码释放free(p);// 如果指针对应的内存被释放,此时指针需要置空,防止产生空悬指针p = NULL;return 0;
}

 注意事项:

        分配内存后需要手动初始化内存,推荐 memset calloc。

        内存空间连续,不可越界访问。

calloc

头文件:

#include <stdlib.h>

 函数原型:

void* calloc(size_t nitems, size_t size);

 功能:动态分配内存,并初始化为0。

 参数:

        nitems :元素个数。

        size :每个元素的字节大小。

 返回值:

        成功 :返回内存指针(申请到的内存的首地址)。

        失败 :失败返回 NULL。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define LEN 5int main()
{// 创建一个指针变量,用来接收内存分配后返回的堆内存地址int *arr = calloc(LEN, sizeof(int)); // 等价于 int *arr = malloc(LEN * sizeof(int); memset(arr,0,LEN * sizeof(int));// 对于指针的使用,一定要进行非空检验,防止野指针if (arr == NULL) // 等价于 !arr{perror("内存申请失败!");return -1;}// 使用for循环快速赋值for (int i = 0; i < LEN; i++){if(i % 2 == 0){continue;}arr[i] = (i+1)*10;}// 遍历数组int *p = arr;for ( ; p < arr + LEN ; p++){printf("%-6d", *p);}printf("\n");// 内存使用完毕,释放内存free(arr);// 置空,防止产生空悬指针arr = p = NULL;return 0;
}

realloc

头文件:

#include <stdlib.h>

函数原型:

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

功能:调整已分配内存块的大小,可能迁移数据到新地址。扩容后,空余位置是随机值,需要手动清零。

原理:

        当前内存空间后面的剩余空间足够扩容,就在原空间基础上进行扩容,返回原地址。

        当前内存空间后面的剩余空间不够扩容,会重新开辟一块空间,将原空间数据按顺序拷贝后,销毁原空间,返回新地址。扩容后的内存空间中的数据是随机的,需要手动清零。

参数:

        ptr :原内存指针,需要扩容的内存空间的指针,这个ptr的来源( malloc/calloc/realloc )。

        size :指定重新分配内存的大小(字节)。

返回值:

        成功 :返回内存指针(申请到的内存的首地址)。

        失败 :失败返回 NULL。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define LEN 5
#define NEW_LEN 8
#define NEW_LEN_MIN 3int main()
{// 创建一个指针,指向堆内存分配的内存空间int *arr = (int*)calloc(LEN, sizeof(int));// 指针的非空检验,防止野指针if (!arr){perror("内存申请失败!");return -1;}// 使用for循环赋值for (int i = 0; i < LEN; i++){arr[i] = (i + 1) * 10;}// 遍历数组int *p = arr;for ( ; p < arr + LEN; p++){printf("%-6d", *p);} printf("\n");// 扩容数组int *temp = (int*)realloc(arr, NEW_LEN * sizeof(int)); // 扩容出来的空间,默认是随机值// 非空校验,防止野指针if(!temp){perror("内存申请失败!");free(arr); // 扩容失败,回收原空间return -1;}// 更新数组指针arr = temp;// 对扩容部分清零memset(arr+LEN,0,(NEW_LEN - LEN) * sizeof(int));// 修改数组元素arr[7] = 666;// 遍历数组for (int i = 0; i < NEW_LEN; i++){printf("%-6d", *(arr + i));}printf("\n");// 缩容数组temp = (int*)realloc(arr, 0); // 此时,会回收掉内存,等价于free(arr);// 非空校验,防止野指针if(!temp){perror("内存申请失败!");return -1;}// 更新数组指针arr = temp;// 遍历数组for (int i = 0; i < NEW_LEN; i++){printf("%-6d", *(arr + i));}printf("\n");// 释放内存free(arr);arr = NULL;p = NULL;return 0;
}

free

头文件:

#include <stdlib.h>

函数原型:

void free(void* ptr);

功能:释放动态分配的内存。

注意事项:

        只能释放一次,重复释放会导致程序崩溃。

        释放后应将指针置为 NULL ,避免野指针。

        栈内存由系统自动释放,无需手动 free

http://www.dtcms.com/a/308835.html

相关文章:

  • 什么是 MySQL 的索引?常见的索引类型有哪些?
  • 【动态规划】数位dp
  • 【AD】域管理员登录错误
  • Google政策大更新:影响金融,Ai应用,社交,新闻等所有类别App
  • 王道考研-数据结构-01
  • Qt_Gif_Creator 基于Qt的屏幕gif录制工具
  • 汽车线束行业AI智能化MES解决方案:推动智能制造与质量升级
  • cpu运行 kokoro tts 服务器语音转化首选
  • 为什么 Batch Normalization 放在全连接/卷积层的输出之后?
  • linux如何将两份hdmi edid合并
  • 硬件电路基础学习
  • Cesium 快速入门(五)坐标系
  • LangGraph底层原理与基础应用入门
  • vue3可编辑表格
  • linux自动构建工具make/makefile
  • 【计算机网络】5传输层
  • MySQL 中的 JOIN 操作有哪些类型?它们之间有什么区别?
  • 国标gb28181 SIP协商详细分析
  • 《嵌入式C语言笔记(十七):进制转换、结构体与位运算精要》
  • .map文件中的0x40f (size before relaxing)是什么意思?
  • 这个项目有多急?
  • MySQL常用函数总结
  • 经典算法之美:冒泡排序的优雅实现
  • 多场景-阶梯式碳交易机制下考虑需求响应的综合能源系统优化(MATLAB模型)
  • 智能Agent场景实战指南 Day 27:Agent部署与可扩展性
  • 本地部署VMware ESXi,并实现无公网IP远程访问管理服务器
  • C++手撕简单KNN
  • 如何使用自定义@DS注解切换数据源
  • 中小企业数据保护指南:如何用群晖NAS构建高效备份体系?
  • pytorch程序语句固定开销分析