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

C语言 ——— 常见的动态内存错误(上篇)

目录

对NULL指针的解引用操作

对动态开辟空间的越界访问 

对非动态开辟内存使用free释放 


对NULL指针的解引用操作

代码演示:

int* ptr = (int*)malloc(sizeof(int) * INT_MAX);
*ptr = 10;
free(ptr);

代码解析:

使用 malloc 函数动态开辟 sizeof(int)*INT_MAX 这么多个字节的空间,而 INT_MAX 是整型类型的最大值,那么肯定会开辟失败,开辟失败就会返回空指针(NULL)

但是开辟失败后没有进行判断,直接对 ptr 指针解引用并且赋值为10,对空指针解引用的话,程序会直接报错,因为空指针没有任何指向的空间,解引用后系统也不知道该指向哪块空间,所以程序会报错

代码验证:

代码改正: 

int* ptr = (int*)malloc(sizeof(int) * INT_MAX);// 判断释放开辟成功
if (ptr == NULL)
{// 报错并结束程序perror("malloc");return -1;
}
else
{*ptr = 10;free(NULL);
}

代码验证:

这样就避免了直接对空指针解引用操作


对动态开辟空间的越界访问 

代码演示: 

int* ptr = (int*)malloc(sizeof(int) * 10);// 判断是否开辟成功
if (ptr == NULL)
{perror("malloc");return -1;
}for (int i = 0; i <= 10; i++)
{ptr[i] = i; //当i是10的时候就是越界访问
}free(ptr);

代码解析:

malloc 函数开辟了 10 个 int 类型的动态空间,并且 ptr 指针指向了起始位置,那么 *(ptr + 0) 表示的是找到了 ptr 所指向的第一个 int 空间的地址,并解引用,那么 *(ptr + 1) 表示的是找到了 ptr 所指向的第二个 int 空间的地址,并解引用

以此类推,ptr[i] = i; 也就是从 ptr 起始位置开始解引用后赋值为 i ,当 i 的值是 0~9 时,刚好就遍历完了 ptr 所指向的 10 个 int 类型的动态空间,但当 i 的值是 10 时,就越界访问了,程序就会报错

代码验证:

代码改正: 

int* ptr = (int*)malloc(sizeof(int) * 10);// 判断是否开辟成功
if (ptr == NULL)
{perror("malloc");return -1;
}for (int i = 0; i < 10; i++)
{ptr[i] = i; //当i是10的时候就是越界访问
}free(ptr);

对非动态开辟内存使用free释放 

代码演示: 

int a = 10;
int* pa = &a;// 对非动态开辟内存使用free释放 
free(pa);

代码验证:

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Parallels Desktop 19 for Mac 安装虚拟机需要激活吗
  • 在不训练模型的情况下强化语言模型
  • 在idea中的git选择某一次记录拉出一个新分支
  • 软考:软件设计师 — 15.数据结构及算法应用
  • 企业级NoSql数据库Redis集群
  • Go 语言切片(Slice)
  • 结构化克隆算法是啥?
  • GoFly快速开发框架已经全部支持市面上见到的主流数据库
  • 语言基础/单向链表的构建和使用(含Linux中SLIST的解析和使用)
  • 【webpack】wabpack5 常用配置
  • 【ORACLE】minus() 函数
  • [数据集][目标检测]快递包裹检测数据集VOC+YOLO格式5382张1类别
  • 聚星文社——Ai推文工具
  • docker-harbor 仓库上传下载镜像以及仓库之间的镜像复制
  • 自学Python网站
  • @angular/forms 源码解析之双向绑定
  • [译]Python中的类属性与实例属性的区别
  • Docker 笔记(2):Dockerfile
  • FineReport中如何实现自动滚屏效果
  • Git初体验
  • Golang-长连接-状态推送
  • HTTP--网络协议分层,http历史(二)
  • Java 23种设计模式 之单例模式 7种实现方式
  • Javascript设计模式学习之Observer(观察者)模式
  • Redis在Web项目中的应用与实践
  • Sass 快速入门教程
  • tab.js分享及浏览器兼容性问题汇总
  • 不发不行!Netty集成文字图片聊天室外加TCP/IP软硬件通信
  • 数据库写操作弃用“SELECT ... FOR UPDATE”解决方案
  • 微服务入门【系列视频课程】
  • 问题之ssh中Host key verification failed的解决
  • 用jquery写贪吃蛇
  • 优化 Vue 项目编译文件大小
  • 终端用户监控:真实用户监控还是模拟监控?
  • 7行Python代码的人脸识别
  • postgresql行列转换函数
  • 昨天1024程序员节,我故意写了个死循环~
  • ​决定德拉瓦州地区版图的关键历史事件
  • ​一帧图像的Android之旅 :应用的首个绘制请求
  • #pragma pack(1)
  • (0)Nginx 功能特性
  • (1)svelte 教程:hello world
  • (152)时序收敛--->(02)时序收敛二
  • (19)夹钳(用于送货)
  • (aiohttp-asyncio-FFmpeg-Docker-SRS)实现异步摄像头转码服务器
  • (arch)linux 转换文件编码格式
  • (C语言)字符分类函数
  • (zhuan) 一些RL的文献(及笔记)
  • (八)Flink Join 连接
  • (笔试题)合法字符串
  • (每日一问)操作系统:常见的 Linux 指令详解
  • (每日一问)设计模式:设计模式的原则与分类——如何提升代码质量?
  • (七)Activiti-modeler中文支持
  • (强烈推荐)移动端音视频从零到上手(下)
  • (转)Android学习笔记 --- android任务栈和启动模式