域名备案期间 网站访问,建设一个公司网站需要多少钱,重庆建设工程岗位培训管理系统,江西省城乡建设陪训网官方网站【作者主页】siy2333 【专栏介绍】⌈c语言日寄⌋#xff1a;这是一个专注于C语言刷题的专栏#xff0c;精选题目#xff0c;搭配详细题解、拓展算法。从基础语法到复杂算法#xff0c;题目涉及的知识点全面覆盖#xff0c;助力你系统提升。无论你是初学者#xff0c;还是… 【作者主页】siy2333 【专栏介绍】⌈c语言日寄⌋这是一个专注于C语言刷题的专栏精选题目搭配详细题解、拓展算法。从基础语法到复杂算法题目涉及的知识点全面覆盖助力你系统提升。无论你是初学者还是进阶开发者这里都能满足你的需求 【食用方法】1.根据题目自行尝试 2.查看基础思路完善题解 3.学习拓展算法 【Gitee链接】资源保存在我的Gitee仓库https://gitee.com/siy2333/study 文章目录 前言一、案例二、越界访问什么是越界访问越界访问一般发生在什么地方数组操作指针操作字符串操作动态内存分配结构体和联合体操作函数调用和参数传递系统调用和库函数并发和多线程网络编程 三、如何避免越界访问数组操作指针操作字符串操作动态内存分配结构体和联合体操作 四、回归案例分析总结 前言
越界访问是一种常见的程序错误本篇文章将基于一个案例从什么是数组越界数组越界经常发生在什么地方如何预防数据越界三方面来详细介绍该错误。 一、案例
查看以下c语言代码试写出其运行结果并说明理由
#include stdio.h
int main()
{int i 0;int arr[] { 1,2,3,4,5,6,7,8,9,10 };for (i 0; i 12; i){arr[i] 0;//数组越界访问printf(%d\t,i);}return 0;
}这个代码非常简洁我们可以很容易的发现其中i的范围是1-12但是arr数组的大小只有10个int类型出现了越界访问。 我们在vs2022中在debug、x86环境下运行该代码结果如下 没错出现了死循环。但是为什么呢
二、越界访问
什么是越界访问
越界访问Out-of-Bounds Access也称为缓冲区溢出或越界读写是一种常见的程序错误。它指的是程序试图访问超出其分配的内存空间的数据。这种行为可能会导致程序崩溃或者被利用来进行恶意攻击。
越界访问一般发生在什么地方
数组操作
数组索引超出范围这是最常见的越界访问类型。例如对于一个大小为10的数组尝试访问第11个元素索引为10就会导致越界。循环控制不当在循环中如果循环条件或索引更新逻辑有误可能会导致索引超出数组范围。例如
int arr[10];
for (int i 0; i 10; i) { // 错误i 10arr[i] i;
}指针操作
未初始化的指针如果指针没有被正确初始化它可能指向一个随机的内存地址解引用这样的指针会导致越界访问。野指针指针指向了一个已经被释放或从未分配的内存区域。指针偏移错误通过指针进行偏移操作时如果偏移量计算错误可能会导致指针指向无效的内存地址。
int arr[10];
int* ptr arr;
ptr 11; // 错误ptr指向了数组范围之外
*ptr 42; // 越界访问字符串操作
字符串长度错误在处理字符串时如果字符串长度计算错误可能会导致越界访问。例如使用strcpy时目标字符串的缓冲区大小不足以容纳源字符串就会导致越界。字符串函数使用不当使用如strcpy、strcat等不安全的字符串函数而不是strncpy、strncat等安全的函数容易导致越界。例如
char dest[10];
char src[] Hello, World!;
strcpy(dest, src); // 错误src长度超过dest的大小动态内存分配
分配大小错误在使用malloc、calloc或realloc分配内存时如果分配的大小不足以满足需求可能会导致越界访问。释放后使用释放了动态分配的内存后仍然尝试访问该内存区域会导致越界访问。例如
int* ptr (int*)malloc(10 * sizeof(int));
free(ptr);
*ptr 42; // 错误ptr指向的内存已经释放结构体和联合体操作
结构体成员访问错误如果结构体的成员访问逻辑有误可能会导致越界访问。例如访问结构体中不存在的成员。联合体使用不当联合体中的成员共享同一块内存如果访问联合体成员时没有正确处理可能会导致越界访问。
函数调用和参数传递
函数参数错误传递给函数的参数如果超出预期范围可能会导致函数内部的越界访问。例如传递给函数的数组指针和数组大小参数不匹配。递归调用错误在递归函数中如果递归条件或递归深度控制不当可能会导致越界访问。
系统调用和库函数
系统调用参数错误在调用系统函数时如果传递的参数不正确可能会导致越界访问。例如使用read或write系统调用时传递的缓冲区大小参数错误。库函数使用不当使用标准库函数时如果参数不正确或使用方式不当可能会导致越界访问。例如使用memcpy时目标缓冲区大小不足以容纳源数据。
并发和多线程
线程同步错误在多线程环境中如果线程同步机制不正确可能会导致多个线程同时访问同一块内存从而导致越界访问。线程局部存储错误如果线程局部存储的使用不当可能会导致越界访问。
网络编程
网络数据处理错误在处理网络数据时如果数据长度计算错误或缓冲区管理不当可能会导致越界访问。例如接收的网络数据长度超过缓冲区大小。协议解析错误在解析网络协议时如果协议解析逻辑有误可能会导致越界访问。
三、如何避免越界访问
数组操作
检查索引范围在访问数组元素之前始终检查索引是否在合法范围内。
int arr[10];
for (int i 0; i 10; i) {arr[i] i;
}使用安全的数组操作函数在C语言中可以使用如strncpy、strncat等安全的字符串操作函数而不是strcpy、strcat等可能导致越界的函数。
char dest[10];
char src[] Hello, World!;
strncpy(dest, src, sizeof(dest) - 1);
dest[sizeof(dest) - 1] \0; // 确保字符串以null字符结尾指针操作
初始化指针确保指针在使用前被正确初始化。
int* ptr NULL;
ptr (int*)malloc(10 * sizeof(int));
if (ptr NULL) {// 处理内存分配失败的情况
}检查指针有效性在解引用指针之前检查指针是否指向有效的内存地址。
if (ptr ! NULL) {*ptr 42;
}避免野指针释放指针后立即将其设置为NULL以避免后续误用。
free(ptr);
ptr NULL;字符串操作
使用安全的字符串函数使用如strncpy、strncat等安全的字符串操作函数而不是strcpy、strcat等可能导致越界的函数。
char dest[10];
char src[] Hello, World!;
strncpy(dest, src, sizeof(dest) - 1);
dest[sizeof(dest) - 1] \0; // 确保字符串以null字符结尾动态内存分配
检查分配大小在使用malloc、calloc或realloc分配内存时确保分配的大小足以满足需求。
int* ptr (int*)malloc(10 * sizeof(int));
if (ptr NULL) {// 处理内存分配失败的情况
}释放后不再使用释放了动态分配的内存后立即将指针设置为NULL以避免后续误用。
free(ptr);
ptr NULL;结构体和联合体操作
检查结构体成员访问在访问结构体成员时确保成员存在且访问逻辑正确。
struct {int a;int b;
} s;
s.a 10; // 正确
// s.c 20; // 错误结构体中没有成员c正确使用联合体联合体中的成员共享同一块内存确保访问联合体成员时逻辑正确。
union {int a;char b[4];
} u;
u.a 0x12345678;
// 正确访问联合体成员四、回归案例分析
我们在第八行添加一个断点并对代码进行调试 我们在监视窗口下逐步观察值的变化 可以看到我们的前十次for循环是正常运行的 那么问题就出现在数组越界后了我们可以修改监视窗口使得arr[10]、arr[11]、arr[12]也可以显示出来。 此时我们可以发现arr[10]、arr[11]是随机值但是arr[12]储存了一个值。当我们执行到arr[12]被修改时监视如下 没错i的值被改变了那么我们可以猜测i的值是否就是储存在arr[12]处使用监视验证这个猜想 答案出来了可以看见arr[12]的地址和i的地址一模一样即因为数组越界访问使得i的值永远无法达到跳出循环的条件。
因此出现了死循环现象。
总结
通过本文的案例分析我们深入探讨了数组越界访问这一常见错误。越界访问不仅会导致程序崩溃还可能引发安全漏洞。本文从越界访问的定义、常见场景及预防方法三个方面进行了详细阐述。在案例中通过调试我们发现数组越界访问导致循环变量 i 的值被意外修改从而引发死循环。
关注窝每三天至少更新一篇优质c语言题目详解~ [专栏链接QwQ] :⌈c语言日寄⌋CSDN [关注博主ava]siy2333 感谢观看~ 我们下次再见!!