C++数组越界的思考

杯子里的绿萝 2009-06-15 06:55:47
继上一个贴字之后我的思考:
————————————————————————————————————————————————————————————————
数组越界

如果申明int a[5];

那么我索引到a[5],a[6]....这些数据是什么样的格式呢?int?还是以int型结构索引?
是不是我定义了int型的数组,然后以int型读取从数组起始地址开始的内存区域吗(包括越界区域的读取)?

例如我上一贴说到的测试程序:

#include <iostream>
using namespace std;

int main()
{
int i;
double a[4];

for (i=0;i<7;i++)
{
a[i]=i;
}
cout<<a[6];

return 0;
}


结果很正常的输出了6,我利用了数组后的内存区域!很显然是我把6赋值给了a[6]的内存区域,但是a[6]究竟是什么呢?为什么它是有意义的?是什么样的结构,是我所猜测的int型吗?

是因为我申明了int型,然后指针从a的地址开始,只要你写a[x],不管x是几,它都将a[x]视作int型操作?

难道数组的申明就是找到一个大于等于申明数组的内存区域,然而你的索引是可以任意的(包括越界,这里不讨论会引起非法操作,只讨论实质),而且都是你以所定义的类型(

如int),这样就可以解释a[6],a[7]....这些数据,到底是怎么样的呢?如我所猜想的那样吗?
有什么书介绍这方面的只是,高手指导一下!

写的有点杂,大家看看我的想法,发表意见!我觉得以这种我这种想法可以很好解释数组越界后的实际操作,但是没有权威支持,希望懂的不懂得都说说自己的想法!

还有推荐一个好的编译器给我!谢谢!
...全文
282 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
C_Plus87 2009-06-15
  • 打赏
  • 举报
回复
这个问题可以参考汇编语言,不管数据还是指令在内存中都是以机器码,当被指令指针寄存器指向或是特定的指令将它当做数据使用时这些存在内存中的数据才有了具体的含义,相同,你定义了int a[4];当数组越界时,编译器还是吧a[5]的那段内存中的数据当成是int(这里只是编译器一厢情愿的把它当成int,但是有些时候这段内存中存储的数据很可能是int不认识的东西,这样程序就崩溃了)
BlueClue 2009-06-15
  • 打赏
  • 举报
回复
这段程序像你这样能正常运行的前提是a[4]之后有未被占用的内存,或者越界的内存可能会被填写,是段不稳定代码。
机智的呆呆 2009-06-15
  • 打赏
  • 举报
回复

#include <iostream>
using namespace std;

int main()
{
int i;
double a[4];

for (i=0;i <7;i++)
{
a[i]=i;
}
cout < <a[6];//如果不考虑对齐的话,给a[4]赋值,就有可能修改i的值,从而有可能陷入死循环。

return 0;
}
机智的呆呆 2009-06-15
  • 打赏
  • 举报
回复
由于c/c++不检查下标,而把控制是否越界的义务交给程序员,从而使c/c++的数组的操作非常接近底层的内存操作。
对于a[i]这种格式,编译器一律解析成*(a+i),这是所谓数组越界的关键。

int a[10]={0};
0[a]=10;
cout<<a[0]<<endl;
int *p=a;
p+=1;
cout<<(-1)[p]<<endl;
cout<<p[-1]<<endl;
chenzhp 2009-06-15
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 crst_zh 的回复:]
引用 6 楼 iwaich 的回复:
我引用和赋值是以将a[6]那块地址当做整型结构,如果原先a[6]连同接下来的四个字节是一个double的结构。那么它将被我破坏,前四个字节被我所使用了。是这样子吗?


是的。int a[6]只是*(a+6),不管那个位置原先是什么东西,只是截取4字节,解释成int而已。
[/Quote]。
yejinson 2009-06-15
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 iwaich 的回复:]
我引用和赋值是以将a[6]那块地址当做整型结构,如果原先a[6]连同接下来的四个字节是一个double的结构。那么它将被我破坏,前四个字节被我所使用了。是这样子吗?
[/Quote]
就是这样,那个区域的数据是垃圾
adventurelw 2009-06-15
  • 打赏
  • 举报
回复
很多时候运行都会产生错误吧,仅仅是编译能够通过。
metaboy 2009-06-15
  • 打赏
  • 举报
回复
学习了!
pengzhixi 2009-06-15
  • 打赏
  • 举报
回复
越界写的话会破坏这些数据。
crst_zh 2009-06-15
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 iwaich 的回复:]
我引用和赋值是以将a[6]那块地址当做整型结构,如果原先a[6]连同接下来的四个字节是一个double的结构。那么它将被我破坏,前四个字节被我所使用了。是这样子吗?
[/Quote]
是的。int a[6]只是*(a+6),不管那个位置原先是什么东西,只是截取4字节,解释成int而已。
杯子里的绿萝 2009-06-15
  • 打赏
  • 举报
回复
我引用和赋值是以将a[6]那块地址当做整型结构,如果原先a[6]连同接下来的四个字节是一个double的结构。那么它将被我破坏,前四个字节被我所使用了。是这样子吗?
pengzhixi 2009-06-15
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 iwaich 的回复:]
就是说,我可以任意索引(不考虑非法情况),并且可以将值赋给它(会改变原内存区域值),并且它的格式是我之前定义的int型?
[/Quote]
你说的 越界的那块内存里面的 数据的类型没办法知道。
比如说 int a[5];
如果你访问a[6]只是表示说你将这数组后面的那4个字节当成int来解释罢了。
xpycc2008 2009-06-15
  • 打赏
  • 举报
回复
a[x] 等价于 x[a] 等价于 *(a+x) ……
goodname 2009-06-15
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 iwaich 的回复:]
就是说,我可以任意索引(不考虑非法情况),并且可以将值赋给它(会改变原内存区域值),并且它的格式是我之前定义的int型?
[/Quote]

是的
杯子里的绿萝 2009-06-15
  • 打赏
  • 举报
回复
就是说,我可以任意索引(不考虑非法情况),并且可以将值赋给它(会改变原内存区域值),并且它的格式是我之前定义的int型?
goodname 2009-06-15
  • 打赏
  • 举报
回复

是因为我申明了int型,然后指针从a的地址开始,只要你写a[x],不管x是几,它都将a[x]视作int型操作?
是这样的。


难道数组的申明就是找到一个大于等于申明数组的内存区域,然而你的索引是可以任意的(包括越界,这里不讨论会引起非法操作,只讨论实质),而且都是你以所定义的类型(
这里应该是等于,不是大于。
对于c/c++不监查数组的边界。即使你的索引是负数也是照此计算的。

65,210

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧