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];
你试试int *a = new int[11];数组实际上放在栈内,new出来的空间是放在堆里面,具体的你需要再找找相关资料看看。
数组是越界了,但越界并不表示一定要报错。
这样的错误,可能会影响程序的功能,但不是报错的条件。也许这样越界后,导致(可能)后面的指针错误,误操作系统区或其它不应该操作的区域,这时才会报错的。
编译器对越界不会报错,但在运行时,如果数组越界,就会使其访问了非法内存,如果跟其它线程冲突,可能会使程序混乱,从而使程序崩溃。
你这里的a[11]肯定是数组越界的,而你读取的a[11] 的值恰好等于11是巧合,如果你再次运行,其值可能就不是11了,而是一个随机的值。
希望能帮到您。
你好,数组越界是不会报错的,C++的就是如此,尽量少做以提高效率,把需要做的交给程序员自己,以达到高效的控制。
至于那个值的巧合,对于a[i]而言,就是相对与首地址a偏移i个单位的内存,你已对那个越界的地址进行了写操作,再读出来并没什么奇怪的,谁让这个程序比较“幸运“,没有崩溃
抱歉,上次没看清代码,这段代码在Vs上测试与你的情况不同,因为VS上对于栈上分配内存,地址并不是递减的
你使用的编译器可能是严格递减的,也就是说 ”i“ 的地址比”a“大 4 * 10 (数组的大小),所以 a[n] 刚好引用的是 ”i“的内存,所以就会有这个巧合
new 11个,索引是0-10,你用11座索引,当然越界了。
编译器的原因,或者说是语言的原因。vc6.0和vs对于c语言、c++不会检测数组越界这个异常。因此编译是可以通过。但是在程序运行时,在内存中并没有a[11]这块内存。这就会导致你查找的数值是一个你并没有赋值的一个“垃圾值”,这个数值是你不受你控制的,因为你根本没就有产生一个变量和数值“指向”。导致了c用起来也非常“危险”。java/c#的编译器会自动检测数组越界异常。
另外,这里使用时用的是数组首地址加上索引乘以单个类型的长度作为地址,然后从这里开始读取制定类型数据,
所以也能读取,数字、字符等应该没有问题,但如果用的是自定义的类型,就可能要报错了。
#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++不进行下标检查
你用liunx系统会报警告
void test1()
{
int i;int a[11];
for(i=0;i<=10;i++)
a[i]=i;
qDebug() << a[11];
qDebug() << a[12];
qDebug() << a[110];
}
调用这个函数后结果是:
2015-07-02 09:42:43:192: Debug: 34111865
2015-07-02 09:42:43:192: Debug: 1899240
2015-07-02 09:42:43:192: Debug: 0
改为release后输出:
2015-07-02 09:43:33:003: Debug: 1736354708
2015-07-02 09:43:33:003: Debug: -378817388
2015-07-02 09:43:33:003: Debug: 0
不是所有程序错误,都导致错误结果的。
数组越界错误,不是编译错误,所以不报错也很平常。
不报错,还能正常输出,还能正常工作的情况很多,不过一旦这种程序,发布出去,就未必也是正常的了
因为,你写的代码。不一定是程序的全部,如果程序里,到处都是此类错误,程序就真的不能正常工作了
这里主要和定义的数组,在内存中的分配的位置有关,
如果数组放置在其他数据中间,那么越界最多,修改了别的数据只要这个数据,暂时不用。那就看不到错误。
如果,如改了函数返回地址,那么就一定会出现莫名其妙的错误
很多高级语言的函数调用返回地址,是存放的堆栈中的,和函数局部变量,
函数参数的数据,是放在一起的。越界的时候,有可能会改变这种数据
那么就危险了