
代码如下:
int i; char *result = (char*)malloc3*sizeof(char)); memset(result, 0, 3*sizeof(char)); for (i = 0; i < 3; i++) { result[i] = 'a'; } result[index] = '#'; 为什么不报错?
1 Monad Jun 15, 2015 不报错从标准上来说应该是undefined behaviour 从实际上来说 是因为ptmalloc2(或者其它memory allocator)会Round Up你malloc的大小,所以你写入的区域实际上是属已经向OS申请的内存区域,而不是OS禁止写入的区域(那样会segmentation fault) |
2 nicai000 Jun 15, 2015 算越界, 不检查不警告, 就这么设计的 |
3 tabris17 Jun 15, 2015 C的数组是不安全的类型,所谓不安全的类型就是语言本身不会越界检查 |
4 xylophone21 Jun 15, 2015 因为这样可以写出 char *result = (char*)0x12345678; 这样的代码 |
5 leavic Jun 15, 2015 底层语言变态的地方就是可以让你访问任意地址,而且很轻松 |
6 xionghengheng Jun 15, 2015 看看malloc的源码你就懂了,谁说堆内存malloc一次就是按照申请多少就给你多少,他可能会给你比你申请内存多一点,这都是内存的动态管理 |
7 ChanneW Jun 15, 2015 再加多少都不算越界 |
8 wy315700 Jun 15, 2015 还可以访问 result[-1] |
9 abscon Jun 15, 2015 说一句跑题的话:index 这个变量在哪里定义的?楼主你这段代码编译通过了吗? |
12 yangff Jun 15, 2015 你可以操作任何一个属于你的地址. |
13 sleeperqp Jun 15, 2015 不能说是任意地址 只能说是该程序的线性地址 |
14 loveuqian Jun 15, 2015 via iPhone 因为越界不报错啊 |
15 zhicheng Jun 15, 2015 谁丫的知道你 index 是啥值。 |
16 icedx Jun 15, 2015 via Android C 语言哪有越界一说 想去哪就去哪 |
17 21grams Jun 15, 2015 那你说说由谁来报这个错呢? |
18 zhangxiao Jun 15, 2015 这就好比一条街上每隔10米一户人家,一共3户(0,1,2)。 写个简单的机器人发,就告诉机器人在n*10的地方丢下包裹就好了。所以你硬要是发给#3,那就丢在了30米的地方,硬要发给#10,就丢在了100米的地方,机器人不管那里有没有住户。 如果让楼主自己去发,你一看就会说,这条街上没有#3啊,就报错了 |
19 thinkIn Jun 15, 2015 via iPhone 虽然越界不会报错,但一定不要做这种事,很可能会覆盖掉malloc与free维护的链表节点头信息,这将会是致命错误。 |
20 zi Jun 15, 2015 C语言的数组名其实是个指针来的,既然是指针,那就可以随便指随便写,至于你随便写之后覆盖掉什么东西。。后果自负。。 |
21 mintist Jun 15, 2015 给你自由,自己把握 |
22 way2exluren Jun 15, 2015 via Android 加句free(result );应该会崩溃 |
23 yaoc Jun 16, 2015 via Android @way2exluren 应该不会,因为result指向的还是一开始分配给它的内存 |
24 way2exluren Jun 16, 2015 via Android @yaoc 你去试试。。。。 |
25 way2exluren Jun 16, 2015 via Android @yaoc 分配好的内存前后都有几个自己是用来管理内存的。覆盖了以后,free再重新整理内存快的时候会出错。。 |
26 yaoc Jun 16, 2015 via Android @way2exluren 我试了,没有什么问题 |
27 alphonsez Jun 16, 2015 试试看多越界一点,估计就出问题了。这种问题会藏的很深,到时候真崩溃了很难找。一个字节的这种,搞不好还能来个heartbleed. |
28 Heartwork Jun 16, 2015 via Android 1 因为malloc在分配的内存是16字节补齐的。所以就算你访问了后面的几个字节,也还是在有效内存范围内。 2 即使你访问了多于16字节的非法空间,还是需要根据brk或sbrk查看数据段末端的地址,如果超过这个值,就会有内存访问异常了。 |