关于数组越界却不会报错

简介: 关于数组越界却不会报错

关于数组越界却不会报错

数组越界是不一定报错的,系统对越界的检查是设岗检查。

一 ,在进行顺序表的学习时遇到的问题,下面是代码,大家可以直接去看结论。

void TestSeqList1() {
  SL s1;
  SLInit(&s1);
  /*SLPushBack(&s1, 1);
  SLPushBack(&s1, 2);
  SLPushBack(&s1, 3);
  SLPushBack(&s1, 4);
  SLPushBack(&s1, 5);
  SLPrint(&s1);*/
  SLPushFront(&s1, 1);
  SLPushFront(&s1, 2);
  SLPushFront(&s1, 3);
  SLPushFront(&s1, 4);
  SLPushFront(&s1, 5);
  SLPrint(&s1);
  SLPopBack(&s1);
  SLPopBack(&s1);
  SLPopBack(&s1);
  SLPopBack(&s1);
  SLPopBack(&s1);
  SLPopBack(&s1);
  SLPushFront(&s1, 4);
  SLPushFront(&s1, 5);
  SLPrint(&s1);
  
}

上图中头插法插入了五个数据 :5 4 3 2 1

下面尾删法删除了六个数据。为什么能删除六个数据呢?看下图尾删法的代码:

void SLPopBack(SL* ps) {
  //assert(ps->size > 0);//防止数组越界,如果数组一越界就会弹出错误;
  ps->size--;//每次数据的大小减小,指针就不会指向被删除的那块内存了;
}

因为每次都会将数据大小减一个,所以导致第六次尾删时会使得 ps -> size = -1.

然后添加两个数据,会发现第一次添加的数据没有被输出,只输出了第二次添加的数据,原因就是 ps -> size = -1 ;第一个添加进-1里面,所以没有被输出。

typedef int SLDataType;
typedef struct seqList {
  SLDataType* a; //因为数组大小固定,为了得到一个动态数组,可以抛弃数组,选择指针。
  SLDataType size;//定义顺序表中的数据的数量。
  SLDataType capacity; //顺序表的容量大小(也就是空间的大小,如何扩容之后会讲)。
}SL;
//头插法
void SLPushFront(SL* ps, SLDataType x) {
  SLCheckCapacity(ps);
  for (int i = ps->size - 1; i >= 0; i--) {
    ps->a[i + 1] = ps->a[i];
  }
  ps->a[0] = x;
  ps->size++;
}

二,结论

根据代码可以有一个疑问,为什么数组下标为-1(可以从头插法代码中可以看到,ps -> size 决定了数组的下标,但是运行没有出错)。

  这是C语言非常重视运行时的效率,检查数据越界,编译器就必须在生成的目标代码中加入额外的代码用于程序运行时检测下标是否越界,这就会导致程序的运行速度下降,且不同的编译器不一样,有些编译器会对越界的检查是设岗检查。例如:int a[5] ;那么就会在a[5],a[6]这些地方严格检查,越界就会报错,但是a[10],a[11] .这些地方就可能不会报错,这就像查酒驾一样,在车流量大的道路口严格检查,在没有车流的道路宽松一点,但这不意味着我们可以在车流量少的路上酒驾(说不定那天就被抓了)。也就是即使数组越界不报错,但是我们也要避免数组越界。

  1. 若是越界的那块地址本来就没有数据占用,就会开辟那块空间用来存储越界的数据(数组开辟的是一串的连续空间)。
  2. 若是越界的那块地址被数据占用,越界的数组就会覆盖那片地址,将会产生严重的数据丢失。
  3. C语言允许数组越界是为了提高效率,但是我们要避免这种事情的发生若是担心越界可以使用assert()断言函数

assert()断言函数

相关文章
|
2月前
|
Rust 安全 Java
内存数组越界
【10月更文挑战第14天】
34 1
|
2月前
|
编译器 C语言
如何检查野指针?
野指针是指未初始化或已释放的指针,检查方法包括:1. 初始化所有指针;2. 使用智能指针;3. 释放后将指针置为 nullptr;4. 利用静态和动态分析工具检测。这些措施可有效避免野指针引发的错误。
|
5月前
|
运维
系统日志使用问题之如何防止在打印参数时遇到NPE(空指针异常)
系统日志使用问题之如何防止在打印参数时遇到NPE(空指针异常)
|
6月前
|
存储 编译器 数据处理
栈溢出及解决方法
栈溢出及解决方法
|
7月前
|
存储 编译器 程序员
C陷阱——数组越界引发的死循环问题
C陷阱——数组越界引发的死循环问题
数组越界死循环问题!
数组越界死循环问题!
56 0
|
编译器 C语言 C++
数组越界访问打印后为什么会陷入死循环
数组越界访问打印后为什么会陷入死循环
97 0
|
编译器 C语言 C++
C语言数组越界造成的死循环例子,当你得到了这个意想不到的结果的时候,你肯定不知道为什么,看你还敢不敢越界访问数组了
C语言数组越界造成的死循环例子,当你得到了这个意想不到的结果的时候,你肯定不知道为什么,看你还敢不敢越界访问数组了
124 0
|
程序员 编译器 C语言
C语言常见问题之数组越界与溢出
C语言常见问题之数组越界与溢出
517 0
C语言常见问题之数组越界与溢出