程序怎么判断数组越界

beyondlwm 2011-06-07 10:16:28
譬如
int a[5];
a[5] = 0;


程序在运行时是怎么判断是否越界?

另外假如
int* p = new int(5);
delete p; //此时变成一个脏指针假设值变成0x12345678

*p = 5;//crash

第三步操作,程序怎么判断对 以0x12345678 开始的内存做操作是违法的?


谢谢!
...全文
5832 69 打赏 收藏 转发到动态 举报
写回复
用AI写文章
69 条回复
切换为时间正序
请发表友善的回复…
发表回复
beyondlwm 2011-06-20
  • 打赏
  • 举报
回复
谢谢楼上,解释得很形象。
xpslone4 2011-06-15
  • 打赏
  • 举报
回复
楼主应该这么想,如果让你自己做一个内存管理器,你如何实现new 和 delete 操作,你如何分配和回收内存,如何判断该内存地址是一个有效的呢,内存一块存储区域,如何使用都是程序管理的,就如系统的内存管理,它分配给你的时候就已经记录了,从哪一地址起始共多少单元为分配的,管理器已经记下了,只有你释放的时候,才又标记为可分配的,要不怎么会有leak一说。

就如你所说,系统如何知道越界了,因为你delete过,系统把这一区域标记为未分配区,你一访问,系统当然要禁止了,要不还能叫操作系统。。。。

上面只是简单的描述, 希望对你有帮助。至于上面有人说不会崩溃的同学,可以在release下面尝试,debug下内存模式是不一样的。。。。
sheepcorpse 2011-06-13
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 beyondlwm 的回复:]

谢谢楼上各位的解答。


我的意思是
当在
int a[5];
a[5] = 0;
的情况下,程序肯定100%会崩溃

说明C++在运行时肯定做过检测,要不然怎么会崩溃呢?

所以我想问这是怎么做到的?
[/Quote]

DEBUG调式模式下,有做内存检测,在申请内存是保留有多余空间来做检测的,并且在释放内存时也是将释放内存段写入无效信息,通过检测无效信息可以做到。
beyondlwm 2011-06-13
  • 打赏
  • 举报
回复
DEBUG调式模式下,有做内存检测,在申请内存是保留有多余空间来做检测的,并且在释放内存时也是将释放内存段写入无效信息,通过检测无效信息可以做到。

嗯,谢谢
那写入无效信息是故意的,对吧?标示该区域已经被释放。
Compass 2011-06-11
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 beyondlwm 的回复:]

谢谢楼上各位的解答。


我的意思是
当在
int a[5];
a[5] = 0;
的情况下,程序肯定100%会崩溃

说明C++在运行时肯定做过检测,要不然怎么会崩溃呢?

所以我想问这是怎么做到的?
[/Quote]



你是用VS系列编译器吧~~~~ VC++就不报错。。
而且VS2008只是在debug模式下报错的。。。
ncite 2011-06-10
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 beyondlwm 的回复:]

谢谢楼上各位的解答。


我的意思是
当在
int a[5];
a[5] = 0;
的情况下,程序肯定100%会崩溃

说明C++在运行时肯定做过检测,要不然怎么会崩溃呢?

所以我想问这是怎么做到的?
[/Quote]

不要想当然,a[5]=0一般不会崩溃的,因为数据区后面有一段缓冲。但有些调试工具会报warning。

如果想内存安全,用managed的语言吧。c\c++玩的就是内存。
魂之木 2011-06-10
  • 打赏
  • 举报
回复 1
int a[5];
可以通过
((&a+1)-a)/sizeof(int)
来得到数组的大小吧,a表示数组首址,这个指针是int型的,&a同样表示数组首址,但&a不是int型的,是int[5]型的,(&a+1)会在首址的基础上加上一个int[5]的大小,也就是指向数组的尾部,然后与首址相减,((&a+1)-a)前面最好加上一个abs(),不大清楚是往内存大的地方加还是小的地方加。如果提示指针不能转为int的话,对应位置加上(int)强转。这个方法可以得到栈上的数组大小的
hewengao401 2011-06-10
  • 打赏
  • 举报
回复
try catch
mltong 2011-06-10
  • 打赏
  • 举报
回复
这个只能自己心里清除了
李子 2011-06-10
  • 打赏
  • 举报
回复
memwatch 用这个工具
beyondlwm 2011-06-10
  • 打赏
  • 举报
回复
delete为什么不直接填充0x00000000呢,哈哈,这样我们还方便点
但是貌似一般都是填充的0Xfefefefe
beyondlwm 2011-06-10
  • 打赏
  • 举报
回复
顺,b2b160的解释最通俗易懂,结贴。
beyondlwm 2011-06-10
  • 打赏
  • 举报
回复
哈哈,楼上的朋友,握紧你的双手。

谢谢大家给的提示,我马上去看一些溢出保护机制的知识。
b2b160 2011-06-10
  • 打赏
  • 举报
回复
其实楼主比很多回答的人研究得更深入,楼主的问题是问机制如何实现,很多人只是针对语言应用进行回答
b2b160 2011-06-10
  • 打赏
  • 举报
回复
对于 release,
delete 是不会判断的
debug版本的做法,是对new的内存填充0xcc
0xcc是代码一个中断int
如果作为代码运行就自动中断在那里
delete的时候也对内存进行填充,通过判断内容是否更改就可以知道是否对野指针赋值了
majia2011 2011-06-10
  • 打赏
  • 举报
回复
菜鸟路过

溢出保护机制,安全类论坛有相关文章(看雪),看不看是你自己的事
mrdone 2011-06-10
  • 打赏
  • 举报
回复
[Quote=引用 41 楼 neolyaoo 的回复:]
引用 1 楼 dizuo 的回复:
没办法的,程序员必须清楚数组有多大。
++
[/Quote]
++
sdlsa10000 2011-06-10
  • 打赏
  • 举报
回复
给lz一棵大树,你造了个独木船,但你却要问:它要怎么样才能在路上跑呢?
na2650945 2011-06-10
  • 打赏
  • 举报
回复
没办法。
用结构体。
带上数组长度。
dotmonkey 2011-06-09
  • 打赏
  • 举报
回复
标题党。。。。
linux平台可以用valgrind,很好用,越界,泄漏都能检测,未初始化的都能检测。
当然原理上不知道是不是跟0xcc一样的道理。
加载更多回复(48)

64,637

社区成员

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

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