- 论坛徽章:
- 2
|
回复 #170 mik 的帖子
具体点的说, 将106的例子更详细的描述一下 :
假设有这样一种机器:
int 是16位, size_t 是16位, 最大的对象大小是 2^16-1。
指针的representation是2个int: (segment, offset)。
或者说, 是一个32位的long —— 是1个数,还是2个数,这都没有关系,不是重点。
当指针被解引用时,需要将representation以某种映射方式转换到一个地址。 根据指针描述的地址空间不同, 映射方式也可以不同。
比如 segment × 16 + offset ?
或者 segment << 16 + offset 。
但是这些映射方式, 都能够将指针的representation, 映射到一个unique的数 —— 地址 —— 用于访问该单元。
这点我是赞同的。
但是, 指针的 ++, --, 并不能保证能够正确反应到它被映射后的数上。举例:
还是上面那种机器,假设指针的 ++ , --是这样实现的:只会改变representation (segment, offset) 中的 offset, 不会引起segment的变化。
这是合理的 —— 对数组 a[ n ], 标准只要求实现能够保证: a +0 到 a + n 不产生溢出。
只变化offset, 并且按标准所说的行事, 就能够满足这种保证 —— 只要指针在a+0到a+n之间, 指针被映射后的数, 也拥有正确的地址。
但是, 在这种机器以及这种指针的实现方式下, 对指针的所有 ++, -- 操作就不能保证全都能被正确反映到指针被映射后的数上了。 除非严格按照标准的要求, 让指针只在 a+0到a+n 之间移动。
比如有一个数组a,大小为326, 起始地址由指针 (1212,0) 标识。
a + 0 就是(1212,0), a +326就是 (1212,326)。 被映射后, 都是合法的地址。
但是a -1? 有可能就是 (1212, 2^16-1) , 映射后的地址可能依然是合法的, 但对lz的case : 逆向遍历数组, 就会形成死循环。 |
|