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. Go资源被墙最快解决方案

    原文链接:https://juejin.im/post/5cd945946fb9a032060c47a3,补充,最新的1.13版本go里默认就是用go module,直接设置代理即可: 注:如果没法升 ...

  2. Appscan 的安装与使用

    一.安装 1.右键安装文件,以管理员身份运行,如下图所示: 2.点击[确定] 3.点击[安装] 4.选择:我接受许可协议中单位全部条款,点击[下一步] 5.点击[安装]到该目录 6.如果需求扫描Web ...

  3. python技巧 — Chrome浏览器中的 XPath Helper

    用于XPath 爬取网页结构的时候使用, 安装后 快捷键调用 左边 ctrl+ shift+x 启动 安装流程: 1. 打开chrome浏览器,扩展程序 .搜索 XPath Helper 下载安装(前 ...

  4. 【HC89S003F4开发板】 2调度器

    HC89S003F4开发板调度器调试 一.前言 逛论坛看到有人给HC89做了调度器,调度部分直接操作堆栈的. 下载链接 下载下来调试看看. 二.用户代码 @实现效果 编译后led灯闪烁 #includ ...

  5. mdk编译时的内存分析

    内存四区(代码区,全局区,栈区,堆区) Code:即代码域,它指的是编译器生成的机器指令,这些内容被存储到ROM区. RO-data:Read Only data,即只读数据域,它指程序中用到的只读数 ...

  6. C++11 特性

    之前工作中开发/维护的模块大多都是 "远古代码",只能编译 C++98,很多 C++11 的特性都忘得差不多了,再回顾一下 右值引用&转移语义: 消除两个对象交互时不必要的 ...

  7. Jira是什么

    JIRA这个工具接触有好几年了,在多个海外项目上都用过这个工具.去年又在项目上深度使用后就有点爱不释手了,回国后也在找机会推荐给其它项目上用.最近正好有新项目需要用,借这个机会把JIRA的配置学习的过 ...

  8. C#使用管理员权限打开cmd执行命令行

    最近遇到个棘手的问题,服务器远程连不上,但是ftp可以,可能远程连接的服务挂了或者防火墙入站规则有点问题,想要重启,得找机房工作人员,还是挺麻烦的 想了想可以上传个执行cmd命令的东西,然后远程访问触 ...

  9. AdventureWorks 安装和配置[转自 微软msdn]

    AdventureWorks 安装和配置 2018/06/19 适用对象:SQL ServerAzure SQL 数据库Azure SQL 数据仓库并行数据仓库 AdventureWorks 下载链接 ...

  10. 解决Vs控制台程序出现NuGet\profile.ps1,因为在此系统上禁止运行脚本错误时或提示:“无法加载文件 \.nuget\packages\Microsoft.EntityFrameworkCore.Tools\1.1.0-preview4-final\tools\init.ps1,因为在此系统上禁止运行脚本”

    1,打开Windows PowerShell 2.输入 set-executionpolicy remotesigned 即可执行脚本 如果执行命令失败的话重新选择Windows PowerShell ...