- 论坛徽章:
- 2
|
回复 45# 变异老鼠
1下标在35楼就说了,它超出C的范围了,而且都能设想出一种可能性。记得以前有过p[-1]的帖子,这里就不重复了。
但其他两个(连续内存、首成员地址)要说超出C范围了吧,也许确实超了;但想不出会产生什么问题。
pmerofc 发表于 2012-05-11 23:21 ![]()
回复 35# OwnWaterloo
C99和C11都特意指出了这是一种未定义行为(附录)
究竟是出于什么深刻的原因
我也不太明白
也许只是有罪推定呢? 制定标准时觉得这没用 —— 都给我用flexible去…… —— 但又是确实他们的失误呢?
为什么是失误?将malloc得到的内存当作二维又或是一维显然必须是对的……
那么问题就来了,就是35楼与36楼的。这问题还可以反问44楼的cfaq:为什么malloc就可以,而自动变量就不行?
比如44楼的cfaq的代码:
- f2(&array[0][0], NROWS, NCOLUMNS);
复制代码 如果改为:
- void* p = malloc(NROWS * NCOLUMNS* sizeof(int));
- f2(p, NROWS, NCOLUMNS);
复制代码 内存大小相同 —— sizeof(array)==NROWS * NCOLUMNS* sizeof(int) —— ,对齐都合乎要求, 就完全没问题。
为什么一个可以,另一个就不可以?
甚至依然用自动变量,但用一个union:
- union {
- int a1[N*M];
- int a2[N][M];
- } u;
复制代码 又该怎么解释?
能想到可能的回答是 —— 就像35楼说的 —— 编译器进行一些边界检查。对a[N],超出[(char*)a,(char*)a+sizeof a)就报错。
而对b[N][M],超出[(char*)b, (char*)b+sizeof b) 的访问报错我觉得可以做到。
但对中间的访问,编译器还能够区分出是通过二维还是一维访问,并且真的这么干了…… 那也管太宽了……
如果这编译器还不提供命令行选项去掉这种功能,至少这编译器我不会去用…… |
|