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语言数组越界的避免方法的更多相关文章

  1. C 语言数组越界导致死循环问题

    今天朋友问我一道 C 语言的题目,如下图: 看到这题一开始也比较纳闷,arr[10] 不是越界了吗?怎么会死循环?怎么 arr[10] 就是 m?这是什么意思? 我们先来看一个简单的例子: ]; ; ...

  2. c语言——数组指针和通过指针引用数组元素的方法总结

    1.数组指针:即指向数组的指针 那么, 如何声明一个数组指针呢?int (* p)[10]; /*括号是必须写的,不然就是指针数组:10是数组的大小*/1拓展:有指针类型元素的数组称为指针数组. 2. ...

  3. C语言 数组做函数参数不传数组个数的遍历方法

    //数组做函数参数不传数组个数的遍历方法 #include<stdio.h> #include<stdlib.h> #include<string.h> void ...

  4. [日常] Go语言圣经-指针对象的方法-bit数组习题

    练习6.1: 为bit数组实现下面这些方法 func (*IntSet) Len() int // return the number of elements func (*IntSet) Remov ...

  5. go语言之进阶篇数组越界导致panic

    1.数组越界导致panic 示例: package main import "fmt" func testa() { fmt.Println("aaaaaaaaaaaaa ...

  6. C语言:数组长度的检测方法

    //数组长度的检测方法 #include <stdio.h> int main() { int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5 ...

  7. Go语言数组和切片的原理

    目录 数组 创建 访问和赋值 切片 结构 初始化 访问 追加 拷贝 总结 数组和切片是 Go 语言中常见的数据结构,很多刚刚使用 Go 的开发者往往会混淆这两个概念,数组作为最常见的集合在编程语言中是 ...

  8. iOS如何彻底避免数组越界

    我们先来看看有可能会出现的数组越界Crash的地方: ? 1 2 3 4 5 6 7 - (void)tableView:(UITableView *)tableView didSelectRowAt ...

  9. Objective-c防止数组越界而崩溃(全局效果)

    数组越界其实是很基本的问题,但是解决起来除了count的判断,还有每个调用的时候都要去判断一遍 对于不明确的数据总会有崩溃的风险 然而 每次调用都判断 那是太累了 so ..runtime&c ...

随机推荐

  1. 软件素材---linux C语言:linux下获取可执行文件的绝对路径--getcwd函数

    //头文件:#include <unistd.h> //定义函数:char * getcwd(char * buf, size_t size); //函数说明:getcwd()会将当前的工 ...

  2. Spring @Transactional 事务机制

    几个概念要清楚:事务的传播机制,事务的边界 工作原理 运行配置@Transactional注解的测试类的时候,具体会发生如下步骤 1)事务开始时,通过AOP机制,生成一个代理connection对象, ...

  3. Ubuntu 18.04 LTS 设置代理(系统代理;http 代理;sock5 代理;apt 代理 ...)

    1. 设置系统代理 1.1 设置 http 代理 1.1.1 只在当前 shell 生效 export http_proxy="http://<user>:<passwor ...

  4. Linux基本命令讲解

    前言 不多BB,直接上图 Linux命令行的组成结构 [root@oldwang ~]# [root@oldwang ~]# [root@oldwang ~]# [root@oldwang ~]# [ ...

  5. 使用Python模块儿csv快速处理csv文件

    代码如下: import csv with open('test.csv',newline='') as f:     reader = csv.reader(f)     for row in re ...

  6. oracle-3-Linux-11g安装-静默安装

    oracle下载地址:https://www.oracle.com/database/technologies/112010-linx8664soft.html 系统是最小化安装的Centos7.2 ...

  7. k8s安装ingress

    1. 环境准备 安装nginx-ingress-controller和backend cd /etc/yum.repos.d/mainfests 下载镜像的脚本 vi ingressnginx.sh ...

  8. Vue响应式变化

    Vue有一个很方便的特性就是Vue的双向绑定,即响应式变化,在Vue2.X版本中,Vue响应式变化靠的是Object.defineProperty方法实现的,但是这个方法有个问题,就是对数组的支持不全 ...

  9. java中的权限修饰符&关键字

    1.类的权限修饰符default(不写权限修饰符),public 说明:类的权限修饰符只有default(不写权限修饰符)和public.   package world default Y N pu ...

  10. JAVA操作ORACLE大对象

    一:操作CLOB  (1)数据库表结构如下:         create table CLOB_TEST      (         ID      VARCHAR2(5) not null,   ...