高效C/C++之九:Coverity修复问题:关于数组操作 和 内存操作

【关注我,后续持续新增专题博文,谢谢!!!】

上一篇我们讲了

        这一篇我们开始讲 高效C/C++之九:Coverity修复问题:关于数组操作 和 内存操作

目录

【关注我,后续持续新增专题博文,谢谢!!!】

一、关于数组操作

    2.1:使用没有初始化的下标变量

    2.2 :下标越界操作

二、:关于内存操作

    2.1:申请和释一一对应

    2.2 :释放后切勿再访问,赋nullptr

    2.3 :关于 delete 和 delete [ ]

    2.4 :对象释放之后再次释放

    2.5 :c/c++内存分配

 

【关注我,后续持续新增专题博文,谢谢!!!】


一、关于数组操作

    2.1:使用没有初始化的下标变量

使用没有初始化的下标变量,进行写入,可能会写入一些系统内存,导致安全风险。

习惯对变量赋值的用法是,先判断变量是否是某个初值,然后进行相关操作,将返回值赋给变量。

异常代码
uint size;
buff[size] = 7;
正确代码
uint size = 0;
buff[size] = 7;

    2.2 :下标越界操作

数组下标越界,读写非法内存,造成内存踩踏,数组下标越界不会被编译器检查到,且会在运行时导致程序随机崩溃。

使用下标之前,需要校验下标是否在数组长度的范围内。

异常代码
char c = buff[offset];
正确代码
if ((offset >= 0) && (offset < size)) {char c = buffer[offset];
} else {return -1;
}

二、:关于内存操作

    2.1:申请和释一一对应

1:栈空间会随着生命周期的消失而消失,堆空间则不会,因为申请的内存一定要去释放;malloc 和 free、new 和 delete、new[]和 delete[] 申请和释放要一一对应;

    2.2 :释放后切勿再访问,赋nullptr

释放的内存包括调用free()、delete()释放的堆内存和函数执行完后自行释放的栈内存,这两类已释放内存如果还被访问,会存在很大风险。

所以我们在释放后,要给指针变量赋值为nullptr,避免野指针,就算再释放nullptr,也不会有问题。

    2.3 :关于 delete 和 delete [ ]

一维数组
int *array=new int [m];
delete [] array;
二维数组
int **array
array = new int *[m];
for (int i=0; i<m; i++ ) {array[i] = new int [n]  ;
}for( int i=0; i<m; i++ ) {delete [] array[i];
}
delete [] array;

对于简单的数组来说 delete [] array 和 delete array,释放效果相同,原因在于:分配简单类型内存时,内存大小已经确定,系统可以记忆并且进行管理,在析构时,系统并不会调用析构函数, 它直接通过指针可以获取实际分配的内存空间,哪怕是一个数组内存空间

class Obj
{public:Obj() { cout << "construct function" <<endl; }~Obj() { cout << "destruct function" <<endl; }
};Obj* ObjArray = new Obj[4];
//1 调用使用类对象的析构函数,2 释放了 ObjArray 指针指向的全部内存空间
delete [] ObjArray;//1 释放了 ObjArray 指针指向的全部内存空间 2 只调用了 ObjArray[0]对象的析构函数
delete ObjArray; 

    2.4 :对象释放之后再次释放

重复关闭内存(double-free)会导致内存管理器出现问题。重复释放内存在一定情况下,有可能导致"堆溢出"漏洞,可以被用来执行恶意代码,具有很大的安全隐患。

所以我们在释放后,要给指针变量赋值为nullptr,避免野指针,就算再释放nullptr,也不会有问题。

    2.5 :c/c++内存分配

int g_int1 = 1;
int g_int2 = 0;
int g_int3;
static int g_sInt1 = 1;
static int g_sInt2 = 0;
static int g_sInt3;int main() {int int1 = 1;int int2 = 0;int int3;static int s_int1 = 1;static int s_int2 = 0;static int s_int3;char *p;char *p1;char cStr[20] = "hello world!";char cStr1[10];char cStr2[10];char *qStr = "hello world!";char *qStr1 = "world hello!";p = (char *)malloc(100);p1 = (char *)malloc(100);/* heap area start */printf("p1                  %p, %d\n", p1, p1);printf("p                   %p, %d\n", p, p);/* heap area end /* stack area start */printf("int1                %p, %d\n", &int1, &int1);printf("int2                %p, %d\n", &int2, &int2);printf("int3                %p, %d\n", &int3, &int3);printf("cStr                %p, %d\n", cStr, cStr);printf("cStr1               %p, %d\n", cStr1, cStr1);printf("cStr2               %p, %d\n", cStr2, cStr2);/* stack area end *//* static area start *//* data segment start */printf("s_int1              %p, %d\n", &s_int1, &s_int1);printf("g_sInt1             %p, %d\n", &g_sInt1, &g_sInt1);printf("g_int1              %p, %d\n", &g_int1, &g_int1);/* data segment end *//* bss segment start */printf("s_int3              %p, %d\n", &s_int3, &s_int3);printf("s_int2              %p, %d\n", &s_int2, &s_int2);printf("g_sInt3             %p, %d\n", &g_sInt3, &g_sInt3);printf("g_sInt2             %p, %d\n", &g_sInt2, &g_sInt2);printf("g_int3              %p, %d\n", &g_int3, &g_int3);printf("g_int2              %p, %d\n", &g_int2, &g_int2);/* bss segment end *//* const segment start */printf("world hello!        %p, %d\n", &"world hello!", &"world hello!");printf("qStr                %p, %d\n", qStr1, qStr1);printf("hello world!        %p, %d\n", &"hello world!", &"hello world!");printf("qStr                %p, %d\n", qStr, qStr);    /* const segment end *//* static area end *//* text area start */printf("code addr start:    %p, %d\n", &main, &main);/* text area start */free(p);free(p1);return 0;
}

【关注我,后续持续新增专题博文,谢谢!!!】

下一篇讲解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/80185.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vfrom表单设计器使用事件机制控制字段显示隐藏

1. 使用表单设计器进行debug调试 依据 vform3.0开发者文档 https://www.ganweicloud.com/docs/6.1.0/pages/d3e6d9/ 对switch组件设置事件逻辑 调试中

iPhone 和 Android 在日期格式方面的区别

整篇文章由iPhone 和 Android 在日期格式方面有所不同引起,大致介绍了,两种时间标准,以及在 JavaScript 下的格式转换方法。 Unix 时间戳是从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数,不考虑闰秒。 iPhone 和 Android 在日期格式方面有所不同。其中,iPhone(iOS)使…

985高校查重率“隐性阈值”:低于5%可能被重点审查!

你是不是也以为&#xff1a; “查重率越低越好&#xff0c;最好压到1%、0%&#xff0c;导师看了都感动哭&#x1f979;” 但是你不知道的是——在985/211等重点高校&#xff0c;查重率太低反而可能引起导师和学术办公室的“特别关注”&#xff01; 今天就来扒一扒这个查重圈“…

【NLP】33. Pinecone + OpenAI :构建自定义语义搜索系统

Pinecone OpenAI 中文教学教程&#xff1a;构建自定义语义搜索系统 一、背景介绍 当下 AI 问答系统、矩阵检索、短文本分类等场景中&#xff0c;都需要很好地实现 “根据输入进行相似给点搜索”。这种算法基础称为 “向量搜索”&#xff0c;它的核心是将文本转换为向量后&am…

【Mybatis-plus常用语法】

MyBatis-Plus 是 MyBatis 的增强工具&#xff0c;提供了很多便捷的功能来简化开发。以下是一些 MyBatis-Plus 的常见语法&#xff1a; 实体类注解&#xff1a;使用 TableName 注解来指定实体类和数据库表的映射关系。 TableName("user") public class User {privat…

Logback官方文档翻译章节目录

Logback官方文档翻译章节目录 第一章 Logback简介 第二章 Logback的架构&#xff08;一&#xff09; Logback的架构&#xff08;二&#xff09; Logback的架构&#xff08;三&#xff09; 持续更新中…

Python变量作用域

变量作用域是Python编程中非常重要的基础概念&#xff0c;理解它可以帮助你避免很多常见的错误。本文将用简单易懂的方式&#xff0c;带你全面掌握Python变量作用域的所有细节。 一、什么是变量作用域&#xff1f; 变量作用域&#xff08;Scope&#xff09;指的是变量在程序中…

初学者的AI智能体课程:构建AI智能体的十堂课

初学者的AI智能体课程:构建AI智能体的十堂课 在人工智能(AI)领域,AI智能体正在逐渐发挥其不容忽视的作用。自动化的智能体不仅仅在理论上广泛讨论,更加在实际应用中开辟了一片新的天地。那么如何动手开发属于自己的AI智能体呢?Microsoft提供的AI智能体入门课正是为此而设…

【并发编程】MySQL锁及单机锁实现

目录 一、MySQL锁机制 1.1 按锁粒度划分 1.2 按锁功能划分 1.3 InnoDB锁实现机制 (1)记录锁(Record Lock) (2) 间隙锁(Gap Lock) (3) 临键锁(Next-Key Lock) (4) 插入意向锁(Insert Intention Lock) 二、基于 JVM 本地锁实现,保证线程安全 2.1 线程不安全的分析 2.1…

能耗优化新引擎:EIOT平台助力企业降本增效

安科瑞顾强 数字化转型的背景下&#xff0c;能源管理正加速向智能化、远程化方向演进。安科瑞电气推出的EIOT托管平台及ADW300系列4G无线计量仪表&#xff0c;通过云端技术与无线通信的深度融合&#xff0c;为用户打造了高效、便捷的远程能源监测与管理体系&#xff0c;助力企…

(14)Element Plus项目综合案例

本系列教程目录&#xff1a;Vue3Element Plus全套学习笔记-目录大纲 文章目录 第3章 综合案例3.1 搭建项目3.1.1 创建Vite工程3.1.2 配置路由 3.2 登录模块页面3.2.1 注册页面3.2.2 登录页面3.2.3 忘记密码页面 3.3 导航设置3.3.1 头部3.3.2 侧边栏与底部1&#xff09;头像部分…

Webug4.0靶场通关笔记22- 第27关文件包含

目录 一、文件包含 1、原理分析 2、文件包含函数 &#xff08;1&#xff09;include( ) &#xff08;2&#xff09;include_once( ) &#xff08;3&#xff09;require( ) &#xff08;4&#xff09;require_once( ) 二、第27关渗透实战 1、打开靶场 2、源码分析 3、…

〖 Linux 〗解决 VS Code 远程连接服务器的常见问题

文章目录 解决 VS Code 远程连接服务器的断开问题VS Code Remote-SSH一直弹出输入密码的问题VsCode C 语法检测失效不标红色波浪线 解决办法卸载扩展方式&#xff1a; 解决vscode C智能提示缓慢 解决 VS Code 远程连接服务器的断开问题 解决 vscode 卡顿&#xff0c;卡死&…

ERC-20与ERC-721:区块链代币标准的双星解析

一、代币标准的诞生背景 在以太坊生态中&#xff0c;代币标准是构建去中心化应用&#xff08;DApps&#xff09;的基石。ERC-20与ERC-721分别代表同质化与非同质化代币的两大核心标准&#xff0c;前者支撑着90%以上的加密资产流通&#xff0c;后者则开启了数字资产唯一性的新时…

C++入门小馆 :多态

嘿&#xff0c;各位技术潮人&#xff01;好久不见甚是想念。生活就像一场奇妙冒险&#xff0c;而编程就是那把超酷的万能钥匙。此刻&#xff0c;阳光洒在键盘上&#xff0c;灵感在指尖跳跃&#xff0c;让我们抛开一切束缚&#xff0c;给平淡日子加点料&#xff0c;注入满满的pa…

【NextPilot日志移植】整体功能概要

整体日志系统的实现功能 该日志系统主要实现了飞行日志的记录功能&#xff0c;支持多种日志记录模式&#xff0c;可将日志存储到文件或通过 MAVLink 协议传输&#xff0c;同时具备日志加密、空间管理、事件记录等功能。具体如下&#xff1a; 日志记录模式&#xff1a;支持按武…

数字化转型:概念性名词浅谈(第二十五讲)

大家好&#xff0c;今天接着介绍数字化转型的概念性名词系列。 &#xff08;1&#xff09;SOP(标准作业程序) 标准作业程序&#xff08;Standard Operating Procedure, SOPs&#xff09;是在有限时间与资源内&#xff0c;为了执行复杂的日常事务所设计的内部程序。从管理学的…

交叉编译 opencv-4.10

编译说明 opencv 下包含很多模块&#xff0c;各个模块的作用可以参考Opencv—模块概览. 嵌入式考虑有限存储等因素会对模块进行裁剪&#xff0c;我这里主要保留图像拼接&#xff08;stitching&#xff09;图片编解码&#xff08;imgcodecs&#xff09;与特征点匹配&#xff08…

Python cv2对象检测与跟踪:从基础到进阶实战

在计算机视觉领域&#xff0c;对象检测&#xff08;定位目标位置&#xff09;与对象跟踪&#xff08;持续追踪目标运动&#xff09;是视频分析、自动驾驶、智能监控等应用的核心技术。本文将结合OpenCV的cv2库&#xff0c;系统讲解其原理与Python实现方法。 一、对象检测 vs 对…

亚马逊推出新型仓储机器人 Vulcan:具备“触觉”但不会取代人类工人

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…