c语言数组越界的避免方法
1、尽量显式地指定数组的边界
#define MAX 10
…
int a[MAX]={1,2,3,4,5,6,7,8,9,10};
在 C99 标准中,还允许我们使用单个指示符为数组的两段“分配”空间,如下面的代码所示:
int a[MAX]={1,2,3,4,5,[MAX-5]=6,7,8,9,10};
在上面的 a[MAX] 数组中,如果 MAX 大于 10,数组中间将用 0 值元素进行填充(填充的个数为 MAX-10,并从 a[5] 开始进行 0 值填充);如果 MAX 小于 10,“[MAX-5]”之前的 5 个元素(1,2,3,4,5)中将有几个被“[MAX-5]”之后的 5 个元素(6,7,8,9,10)所覆盖。
2、对数组做越界检查,确保索引值位于合法的范围之内
传递数组参数的时候,一定要带上传入数组的长度,比如:
void Init(int arr[],size_t arr_len)
{
size_t i=0;
for(i=0;i<arr_len;i++)
{
arr[i]=i;
}
}
arr_len类型一定要无符号,避免负数的副作用。
3、获取数组的长度时不要对指针应用 sizeof 操作符。
单地讲,sizeof 是一个单目操作符,不是函数。其作用就是返回一个操作数所占的内存字节数
下面的函数中,使用sizeof,以为是对的,其实,arr传进来的时候,已经退化为指针,所以等同于
void Init(int *arr)。
void Init(int arr[])
{
size_t i=0;
for(i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
{
arr[i]=i;
}
}
4、除此之外,我们还可以通过指针的方式来解决上面的问题,示例代码如下所示:
void Init(int (*arr)[10])
{
size_t i=0;
for(i=0;i< sizeof(*arr)/sizeof(int);i++)
{
(*arr)[i]=i;
}
}
int main(void)
{
int i=0;
int a[10];
Init(&a);
for(i=0;i<10;i++)
{
printf("%d\n",a[i]);
}
return 0;
}
现在,Init() 函数中的 arr 参数是一个指向“arr[10]”类型的指针。
需要特别注意的是,这里绝对不能够使用“void Init(int(*arr)[])”来声明函数,编译器会报错:error: sizeof applied to an incomplete type
而是必须指明要传入的数组的大小,否则“sizeof(*arr)”无法计算。但是在这种情况下,再通过 sizeof 来计算数组大小已经没有意义了,因为此时数组大小已经指定为 10 了。
c语言数组越界的避免方法的更多相关文章
- C 语言数组越界导致死循环问题
今天朋友问我一道 C 语言的题目,如下图: 看到这题一开始也比较纳闷,arr[10] 不是越界了吗?怎么会死循环?怎么 arr[10] 就是 m?这是什么意思? 我们先来看一个简单的例子: ]; ; ...
- c语言——数组指针和通过指针引用数组元素的方法总结
1.数组指针:即指向数组的指针 那么, 如何声明一个数组指针呢?int (* p)[10]; /*括号是必须写的,不然就是指针数组:10是数组的大小*/1拓展:有指针类型元素的数组称为指针数组. 2. ...
- C语言 数组做函数参数不传数组个数的遍历方法
//数组做函数参数不传数组个数的遍历方法 #include<stdio.h> #include<stdlib.h> #include<string.h> void ...
- [日常] Go语言圣经-指针对象的方法-bit数组习题
练习6.1: 为bit数组实现下面这些方法 func (*IntSet) Len() int // return the number of elements func (*IntSet) Remov ...
- go语言之进阶篇数组越界导致panic
1.数组越界导致panic 示例: package main import "fmt" func testa() { fmt.Println("aaaaaaaaaaaaa ...
- C语言:数组长度的检测方法
//数组长度的检测方法 #include <stdio.h> int main() { int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5 ...
- Go语言数组和切片的原理
目录 数组 创建 访问和赋值 切片 结构 初始化 访问 追加 拷贝 总结 数组和切片是 Go 语言中常见的数据结构,很多刚刚使用 Go 的开发者往往会混淆这两个概念,数组作为最常见的集合在编程语言中是 ...
- iOS如何彻底避免数组越界
我们先来看看有可能会出现的数组越界Crash的地方: ? 1 2 3 4 5 6 7 - (void)tableView:(UITableView *)tableView didSelectRowAt ...
- Objective-c防止数组越界而崩溃(全局效果)
数组越界其实是很基本的问题,但是解决起来除了count的判断,还有每个调用的时候都要去判断一遍 对于不明确的数据总会有崩溃的风险 然而 每次调用都判断 那是太累了 so ..runtime&c ...
随机推荐
- LeetCode 100. 相同的树(Same Tree) 2
100. 相同的树 100. Same Tree 题目描述 给定两个二叉树,编写一个函数来检验它们是否相同. 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的. 每日一算法2019/5 ...
- python(自用手册)
第二章 入门 python简介 python是一个解释型语言是一个强语言 编译型 把每一条语句都提前编译成机器语言,保存成二进制以便计算机运行可以脱离环境运行 优点 预编译使用前直接编译成计算机可以识 ...
- python 之 面向对象基础(继承与派生,经典类与新式类)
7.2 继承与派生 7.21继承 1.什么是继承? 继承是一种新建类的的方式,在python中支持一个子类继承多个父类.新建的类称为子类或者派生类,父类又可以称为基类或者超类,子类会”遗传“父类的属性 ...
- Scala 面向对象编程之Trait
将trait作为接口使用 // Scala中的Triat是一种特殊的概念 // 首先我们可以将Trait作为接口来使用,此时的Triat就与Java中的接口非常类似 // 在triat中可以定义抽象方 ...
- 【数论】小A进学校
小A进学校 题目描述 近日,清华大学挖出来一个明清古墓.小A决定冒充考古系科研人员去盗墓.他遇到的第一个难关是来自校门口保安的质疑,因为小没有清华学生证,所以保安决定通过问问题的方式验证小A的身份. ...
- PowerBuilder学习笔记之导入Excel数据
原文地址:http://blog.chinaunix.net/uid-20586802-id-3235549.html /*****************简单的导入功能,涉及到数据类型判断***** ...
- vue 写一个瀑布流插件
效果如图所示: 采用了预先加载图片,再计算高度的办法..网络差的情况下,可能有点卡 新建 vue-water-easy.vue 组件文件 <template> <div class ...
- 2.Excel VBA术语
Excel VBA名词术语 在这一章中,让我们了解常用的Excel VBA术语.这些术语将在进一步模块学习中使用,因此理解它们是非常关键的. 模块 1.模块是其中代码被写入的区域.这是一个新的工作簿, ...
- dotnetcore 与 hbase 之三——c# for hbase 客户端的使用
说明 在上一篇文章dotnetcore 与 hbase 之二--thrift 客户端的制作中已经可以找到 c# hbase 客户端的使用方法了,为什么这里单独列出一篇文章来讲述呢?最简单的理由就是,本 ...
- PAT-1111 Online Map (30分) 最短路+dfs
明天就要考PAT,为了应付期末已经好久没有刷题了啊啊啊啊,今天开了一道最短路,状态不是很好 1.没有读清题目要求,或者说没有读完题目,明天一定要注意 2.vis初始化的时候从1初始化到n,应该从0开始 ...