使用数组也是家常便饭,但是经常出现越界使用数组也能编译通过的奇怪问题,和我们书中学习的很不一样,怎么折腾也不知道为什么,郁闷了吧!哈哈哈,别慌,这里就给你答案啦。

函数中分配的数组,不是使用动态分配的那就就是自动分配的,就是在线程栈的内存空间分配的。如果使用动态分配,即使用malloc或者new等来分配的,则是在堆中分配的。堆是是一块单独的内存块,供各个进程线程来使用的。而在栈中分配的内存,会自动分配,使用完后自动释放。我们从来都是定义一个数组变量,然后用完就不管了,根本也没有管数组的释放,因为超过数组的作用范围后,自动就销毁了,释放了占用的栈内存。

这个栈是每个进程中的,进程中创建一个线程,就会为线程在进程空间中分配一块内存给线程使用,这个内存就是线程栈。我们说的栈都是指线程栈。线程栈有一定大小,用于函数调用存储参数,记录调用函数的返回地址,用于函数返回到调用函数的位置继续执行,还用于分配局部自动变量。

栈的空间就是一段内存。我们使用数组就在栈中分配,那么对数组操作,起始就是对数组对应的栈地址进行操作。下面给出数组使用的代码,在VC中编译通过。

char t[5];

t[8]=0;

这两句代码的意思是:分配一个5个字节的数组,然后对数组中的第九个元素赋值为0.

这就已经越界了。但是在VC编译时不报错。在Debug模式下,运行会报错。而在Release模式下,没有任何问题。为什么呢?

虽然数组越界了,但是Release模式依然放行,这就给程序带来隐患,这个很可能在运行过程中破坏了线程栈,导致程序崩溃。比如,t[8]的位置刚好是调用函数返回地址,地址是四个字节,但是结果其中一个字节却被清零了,这样导致返回地址破坏了。那么函数无法返回,从而程序崩溃了。

那为什么只有在Debug模式下才能检测出来而Release模式为什么不行呢?为什么编译又能通过呢?

在Debug模式下,代码中是加入了检测跟踪代码的,可以便于调试,自然这样就可以容易检查出来。因为加入了调试代码,自然生成的EXE就比较大。而Release模式则去掉了这些跟踪检测代码,自然就不会检测这些东西了。对于这些的检测,程序员要在Debug模式下通过,最后发布是才用Release模式生成EXE,不要使用Release模式调试程序哦。

而编译通过的原因,则是因为,及时数组越界,但是因为越界的范围比较小,操作的内存地址在线程栈的范围之中,不可能出现内存操作违规的情况,编译器也没办法分清楚正确与否,所以也就通过了。

但是,编译通过和运行暂时没有出现问题,不代表没有问题,越界后是有隐患的。一般情况还是很严重的。特别要防范好,以免造成巨大的损失。

这个问题在将局部变量的地址当做函数返回值,这个问题也是很难检查出来的,如果不对这个地址赋值等,一般也不会有什么问题,一旦对这个赋值,且这个地方正好被其他参数使用了,那么就会造成线程栈破坏,导致程序崩溃。而当时你很可能发现不了这个问题,却留下了隐患。

所以,如果程序崩溃出现线程栈破坏的情况,请检查数组越界、返回局部变量地址等等问题。在开发软件时一定要养成好习惯,不要犯这种错误,一般这种错误时很难定位的。

oracle数组越界,为什么栈中的数组越界后经常不崩溃,还可以正常的操作呢相关推荐

  1. c语言数组的存储与越界,C语言中的数组越界问题解决方法

    1.数组越界,是指访问了超出数组定义的内容. 实例: int  a[2]; 数组a定义了2个元素! a[0],a[1]:没有越界. a[2]:越界了! 对不对? 2.计算机全部的内存,其地址是从小到大 ...

  2. 多维数组和C#中的数组数组有什么区别?

    C#中的多维数组double[,]和数组数组double[][]什么区别? 如果存在差异,那么每个最好的用途是什么? #1楼 前言:此评论旨在解决okutane提供的答案 ,但是由于SO的愚蠢信誉系统 ...

  3. JAVA中一维数组的作用,JAVA中一维数组和二维数组的定义

    在java中数组被看成是一个对象 在定义数组时,有两种定义方法:int[] a 和int a[]:第二种是C/C++对数组定义方式,对于JAVA建议采用第一种定义方式. 总的原则:任何对象在被调用之前 ...

  4. 输出php数组结构,在PHP中输出数组结构使用 函数 。

    在PHP中输出数组结构使用 函数 . 更多相关问题 南京长江第三大桥是什么时候通车的?() 抗爆性可以判断汽油在发动机中燃烧是否易于发生不正常的(). 道岔尖轨.心轨.基本轨的爬行.窜动量不得超()m ...

  5. verilog中数组的定义_systemverilog中的数组操作

    sv中的数组基本操作:/* Exercsise platform :     Questa Sim 10.1b */ class Array; int array[9:0] ; function ne ...

  6. vue 监听map数组变化_vuex state中的数组变化监听实例

    前言 首先,因为我有一个需求就是vue组件中有一组多选框,选中多选框的内容,要在另一个组件中进行视图更新,这个就设计的兄弟组件之间的通信了,兄弟组件之前通信我首先选用的vuex这个解决办法. 问题 v ...

  7. matlab单元数组和结构,Matlab中单元数组和结构数组

    前言: 单元数组和结构数组是一种新的数据类型,能将不同类型.不同维数的数组组合在一起,从而方便对不同的数据类型方便管理和维护. 如上图所示的2*2矩阵中,分别存储着四种不同的数据类型,分别为数组.字符 ...

  8. java整型转换为数组_基于java中byte数组与int类型的转换(两种方法)

    java中byte数组与int类型的转换,在网络编程中这个算法是最基本的算法,我们都知道,在socket传输中,发送.者接收的数据都是 byte数组,但是int类型是4个byte组成的,如何把一个整形 ...

  9. java数组循环扩容_Java中实现数组动态扩容的两种方法

    Java中实现数组动态扩容的两种方法 java中初始化一个数组需要定义数组的容量,而在我们使用数组时往往会遇到数组容量不够的情况,此时我们就需要通过动态扩容的方式来来根据需求扩大数组的容量. 我们可以 ...

最新文章

  1. 测试思想 什么是软件测试(摘录)
  2. 两次杀人,自动驾驶技术之恶
  3. POJ 1976 A Mini Locomotive【DP】
  4. windows环境运行MongoDB
  5. python人工智能-Python和人工智能的关系,看完你就明白了!
  6. c语言 sdk,适用于 C 语言的 Azure IoT 设备 SDK
  7. Python字符串格式:%vs.format
  8. SIFT算法详解(附有完整代码)
  9. 【软技能】完全写作指南
  10. 风暴孵化分享:新手小白想做手游代理可不可以?
  11. 微型计算机的主机常用部件,组成微型机主机的部件是
  12. 安装 dpdk-ans 时的编译问题:librte_ans.a(ans_init.o): unrecognized relocation (0x2a) in section `.text'
  13. 跨越华为职业生涯的沟沟坎坎
  14. 【学习总结】VIO初始化学习1:Monocular Visual–Inertial State Estimation With Online Initialization and Camera–IMU
  15. 财付通开放平台 android,腾讯开放财付通对接平台
  16. LCG(linear congruential generator)伪随机数生成器
  17. 【Linux词典】之磁盘命令(fdisk、gdisk、mkswap、mount、umount、df、lsblk)
  18. 前端:blob转换为图片URL,但是图片不显示
  19. SQL 索引超详细解析
  20. 2022年起重机司机(限门式起重机)考试题模拟考试题库及答案

热门文章

  1. spring-boot-2.0.3启动源码篇五 - run方法(四)之prepareContext
  2. 数商云S2B2C电商系统结算功能助力化工行业规避结算风险,提升结算管理能力
  3. 迅为IMX6ULL开发板更新资料介绍
  4. 用sql dts导入mysql数据库,使用命令行导入sql文件到mysql数据库
  5. 郁金香vc++过驱动保护游戏外挂制作教程1-51课全套
  6. ADS中导入SPICE模型
  7. convert命令FAT32转NTFS(不影响硬盘数据)
  8. android 选择打开系统软件解压缩zip包
  9. 使用python和pyqt5轻松上手人脸识别系统(含代码)
  10. Tunnelblick mac是一款在主机操作系统上运行VP~解决方案的跳板软件。