2 chenzhichao chenzhichao 于 2015.06.29 06:47 提问

一个关于数组溢出的问题,请大神帮小弟解惑

vc6.0环境,代码很简单,但是不管你输入的数组n是多大,a[n]的值都是n,按理说不是最大就到n-1了吗,为什么不报错?
#include
using namespace std;
int main()
{int i;int a[11];
int*p=a;
for(i=0;i<=10;i++)
a[i]=i;
cout<<a[11];

return 0;
}
图片说明

13个回答

wangyu21505115
wangyu21505115   2015.06.29 07:58

你试试int *a = new int[11];数组实际上放在栈内,new出来的空间是放在堆里面,具体的你需要再找找相关资料看看。

91program
91program   Ds   Rxr 2015.06.29 08:32

数组是越界了,但越界并不表示一定要报错。
这样的错误,可能会影响程序的功能,但不是报错的条件。也许这样越界后,导致(可能)后面的指针错误,误操作系统区或其它不应该操作的区域,这时才会报错的。

yxjie2
yxjie2   2015.06.29 08:40

编译器对越界不会报错,但在运行时,如果数组越界,就会使其访问了非法内存,如果跟其它线程冲突,可能会使程序混乱,从而使程序崩溃。
你这里的a[11]肯定是数组越界的,而你读取的a[11] 的值恰好等于11是巧合,如果你再次运行,其值可能就不是11了,而是一个随机的值。

希望能帮到您。

chenzhichao
chenzhichao 回复心飞乐: 谢谢!
2 年多之前 回复
yxjie2
yxjie2 我上面是经过实测你的代码了才回答你的问题的,不过我用的是VS2013的c++。你可以这样分析一下:你在“cout<<a[11];”这一句设置一个断点,然后调试,调出内存查看窗口,输入数组a的地址,看看这一块内存的内容就找到原因了。
2 年多之前 回复
chenzhichao
chenzhichao 朋友你可以试一下,这不是偶然,你随便试多大的数组多少次都是这个结果
2 年多之前 回复
u011547347
u011547347   2015.06.29 09:12

你好,数组越界是不会报错的,C++的就是如此,尽量少做以提高效率,把需要做的交给程序员自己,以达到高效的控制。
至于那个值的巧合,对于a[i]而言,就是相对与首地址a偏移i个单位的内存,你已对那个越界的地址进行了写操作,再读出来并没什么奇怪的,谁让这个程序比较“幸运“,没有崩溃

chenzhichao
chenzhichao 这不是偶然,你可以在VC平台上随便实验多少次都是这个结果,cout<<a[11]得到的都是11,甚至不管多大的数组都一样
2 年多之前 回复
chenzhichao
chenzhichao 这不是偶然,你可以在VC平台上随便实验多少次都是这个结果,cout<<a[11]得到的都是11,甚至不管多大的数组都一样
2 年多之前 回复
u011547347
u011547347   2015.06.29 09:17

抱歉,上次没看清代码,这段代码在Vs上测试与你的情况不同,因为VS上对于栈上分配内存,地址并不是递减的
你使用的编译器可能是严格递减的,也就是说 ”i“ 的地址比”a“大 4 * 10 (数组的大小),所以 a[n] 刚好引用的是 ”i“的内存,所以就会有这个巧合

maidi_2015
maidi_2015   2015.06.29 09:21

编译器的原因,或者说是语言的原因。vc6.0和vs对于c语言、c++不会检测数组越界这个异常。因此编译是可以通过。但是在程序运行时,在内存中并没有a[11]这块内存。这就会导致你查找的数值是一个你并没有赋值的一个“垃圾值”,这个数值是你不受你控制的,因为你根本没就有产生一个变量和数值“指向”。导致了c用起来也非常“危险”。java/c#的编译器会自动检测数组越界异常。

guyueyan577
guyueyan577   2015.06.29 09:21

new 11个,索引是0-10,你用11座索引,当然越界了。

chenzhichao
chenzhichao 但是越界了为什么还能正常输出?注意,这不是偶然,试了多少次cout<<a[11]都是这个结果
2 年多之前 回复
guyueyan577
guyueyan577   2015.06.29 09:25

另外,这里使用时用的是数组首地址加上索引乘以单个类型的长度作为地址,然后从这里开始读取制定类型数据,
所以也能读取,数字、字符等应该没有问题,但如果用的是自定义的类型,就可能要报错了。

u012565112
u012565112   2015.06.29 09:48

#include
using namespace std;
int main()
{int i;int a[11];
int*p=a;
for(i=0;i<=10;i++)
a[i]=i;
cout<<a[11];

return 0;
}

c++不进行下标检查

u012565112
u012565112   2015.06.29 09:49

你用liunx系统会报警告

chenzhichao
chenzhichao 我知道越界,可是为什么越界了还能正常输出,并且,这不是偶然,你试验多少次都是是这个结果
2 年多之前 回复
共13条数据 1 尾页
Csdn user default icon
上传中...
上传图片
插入图片