C++数组下标越界竟然不触发异常!!

如题。

今天才发现,原来C++从来不检查数组索引是否越界。访问数组元素,比如a[3]时,编译器其实已经处理成了*(a+3),这时候已经没有数组的概念了,检查数组长度就更无从谈起。

这一特性使我遇到了一个非常大的BUG,把它简化成下面的代码:

#include <iostream>

int main() {

    double d[3] = {0, 1, 2};
    double dd = 9;

    d[3] = 0;

    std::cout << dd << std::endl;

    return 0;
}

输出结果是0而不是9。

也就是说,给d[3]赋值实际上赋到了dd头上去了。因为数组d和变量dd被依次定义,它们被安排在同一块内存空间的相邻位置,于是d[3]实际指向的是dd的内存空间,因此dd被改写。

在实际编程中,这样的问题很容易出现,但非常难排查。被覆盖的变量可以是基本数据类型,也可以是变量,还可以是指针。而且有时候变量并不一定按照定义时的顺序排列在内存中,编译器完全有可能做了额外的优化,重排这些变量的位置。据说C++是为了提高效率,才弱化了安全保护机制,毕竟两者不可兼得。

编程难,编C++更难,且编且珍惜。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 指针是C语言中广泛使用的一种数据类型。 运用指针编程是C语言最主要的风格之一。利用指针变量可以表示各种数据结构; ...
    朱森阅读 3,509评论 3 44
  • 数组在程序设计中,为了处理方便, 把具有相同类型的若干变量按有序的形式组织起来。这些按序排列的同类数据元素的集合称...
    朱森阅读 4,068评论 2 13
  • 1.OC里用到集合类是什么? 基本类型为:NSArray,NSSet以及NSDictionary 可变类型为:NS...
    轻皱眉头浅忧思阅读 1,399评论 0 3
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,239评论 30 472
  • 踏入大学新社会 无知伴随你左右 新鲜事物看不够 有的只是一夜情 来来往往不知多 大多只是一过客 美女佳肴有好多 但...
    一御而飞阅读 176评论 0 2