当前位置: 技术问答>linux和unix
为什么越界错误没有被检测到?
来源: 互联网 发布时间:2015-09-19
本文导语: 我在Red Hat9下编写了如下一个程序: #include int main(void) { printf("Hello World!"); ...
我在Red Hat9下编写了如下一个程序:
#include
int main(void)
{
printf("Hello World!");
int a[2];
a[6]=4;
int *p;
printf("a[6]=%d,p[2]=%dn",a[6],p[2]);
return 0;
}
使用gcc Test.c -o Test编译后执行,为什么能够正常执行?我的数组都已经越界了啊!
请各位指教,如何才能让这段程序在执行时报错呢?
(但当我把int *p;该为int *p=NULL;时,运行程序就会报段错误)
#include
int main(void)
{
printf("Hello World!");
int a[2];
a[6]=4;
int *p;
printf("a[6]=%d,p[2]=%dn",a[6],p[2]);
return 0;
}
使用gcc Test.c -o Test编译后执行,为什么能够正常执行?我的数组都已经越界了啊!
请各位指教,如何才能让这段程序在执行时报错呢?
(但当我把int *p;该为int *p=NULL;时,运行程序就会报段错误)
|
C或C++的编译器没有检测内存泄露的功能。
至于你的程序能够正常运行是因为数组越界后正好没有覆盖OS所不允许的区域。这种代码在实际的项目中往往是莫明奇妙的错误(比如程序不定时的core dump等等)的根源。
至于你的程序能够正常运行是因为数组越界后正好没有覆盖OS所不允许的区域。这种代码在实际的项目中往往是莫明奇妙的错误(比如程序不定时的core dump等等)的根源。
|
我希望每次产生越界错误的时候都出现core dump.
这个似乎不可能,如果越界后所覆盖的区域不是受OS保护的,就不会CORE DUMP
WINDOWS 下也不会每次都出现越界错误。试试在VC下运行下面的程序:
#include
void main()
{
char buff[4];
sprintf ( buff , "%10s" , "1234567890");
puts ( buff );
}
这个似乎不可能,如果越界后所覆盖的区域不是受OS保护的,就不会CORE DUMP
WINDOWS 下也不会每次都出现越界错误。试试在VC下运行下面的程序:
#include
void main()
{
char buff[4];
sprintf ( buff , "%10s" , "1234567890");
puts ( buff );
}
|
LINUX 的内存分配并不是需要几个字节就给你几个字节的,一般来讲按页分配,最后一页又通常可能被几个进程共享,分配的字节一般总是比需要的要多一些,如果a[6]=4; 指针跳跃更大一些,可能就出问题了。
|
对于a[6]:因为是在函数中声明的数组,所以是在堆栈中存放的,而linux堆栈的增长方向是从高地址到低地址的。因此p所在的地址最小:
a[1]: bffff944
a[0]: bffff940
p addr: bffff93c
而a[6]显然是修改了别的什么地方,但是操作系统是不会对堆栈的指针进行越界保护的。
对于p[2]:
因为你只是引用了p[2]的值,并没有对p[2]进行赋值,所以不会出现segmentation fault的~~~~~
a[1]: bffff944
a[0]: bffff940
p addr: bffff93c
而a[6]显然是修改了别的什么地方,但是操作系统是不会对堆栈的指针进行越界保护的。
对于p[2]:
因为你只是引用了p[2]的值,并没有对p[2]进行赋值,所以不会出现segmentation fault的~~~~~
|
c/c++不进行越界检测,java可以
int *p; //指针有个随机值,所以p[2]可能不会错。
int *p=NULL; //空指针,当然访问p[2]出错
int *p; //指针有个随机值,所以p[2]可能不会错。
int *p=NULL; //空指针,当然访问p[2]出错
|
嗬嗬,还是要养成良好的语言习惯,比什么都强啊
|
越界当然不一定就出错了