pointers - 为什么存在标记指针
问题描述
我了解标记指针背后的理论以及如何使用它在指针中保存其他数据。
但我不明白这部分(来自关于标记指针的维基百科文章)。
大多数架构都是字节可寻址的(最小的可寻址单元是一个字节),但某些类型的数据通常会与数据的大小对齐,通常是一个字或多个字。这种差异使指针的一些最低有效位未被使用
为什么会这样?
指针是否只有 30 位(在 32 位架构上)并且 2 位是对齐的结果?
为什么首先有 2 口未使用?
这是否会减少可寻址空间的大小(从 2^32 字节到 2^30 字节)?
解决方案
考虑一个使用 16 位对齐和 16 位指针的架构(只是为了避免有太多的二进制数字!)。指针只会引用 16 的倍数的内存位置,但指针值仍然精确到字节。所以二进制指针是:
0000000000000100
指内存位置 4(内存中的第五个字节):
┌────────────────────┬────────────────────┬──────── ──────┬──────────────┐ │ 十进制地址 │ 二进制地址 │ 8─位字节 │ 16位字 │ ├────────────────────┼────────────────────┼──────── ──────┼──────────────┤ │ 0 │ 000000000000000 0 │ ┌──────────┐ │ ┌──────────┐ │ │ │ │ └─────────┘ │ │ │ │ │ 1 │ 0000000000000001 │ ┌──────────┐ │ │ │ │ │ │ │ └────────┘ │ └──────────┘ │ │ 2 │ 000000000000001 0 │ ┌──────────┐ │ ┌──────────┐ │ │ │ │ └─────────┘ │ │ │ │ │ 3 │ 0000000000000011 │ ┌──────────┐ │ │ │ │ │ │ │ └────────┘ │ └──────────┘ │ │ 4 - 这个 │ 000000000000010 0 │ ┌──────────┐ │ ┌────────┐ │ │ │ │ └─────────┘ │ │ │ │ │ 5 │ 0000000000000101 │ ┌──────────┐ │ │ │ │ │ │ │ └────────┘ │ └──────────┘ │ │ 6 │ 000000000000011 0 │ ┌──────────┐ │ ┌──────────┐ │ │ │ │ └─────────┘ │ │ │ │ │ 7 │ 0000000000000111 │ ┌──────────┐ │ │ │ │ │ │ │ └────────┘ │ └──────────┘ │ │ ... │ │ │ │ └────────────────────┴────────────────────┴──────── ──────┴──────────────┘
使用 16 位对齐,将永远不会有指向内存位置 5 的指针,因为它不会对齐,下一个有用的值是 6:
0000000000000110
请注意,最低有效位(最右边的那个)仍然是 0。事实上,对于该架构上的所有有效指针值,该位将为 0。这就是他们留下“......一些指针的最低有效位未使用。” 在我的示例中,它只有一位,但如果您有 32 位对齐,则指针值末尾的两位将始终为零:
┌────────────────────┬────────────────────┬──────── ──────┬──────────────┐ │ 十进制地址 │ 二进制地址 │ 8─bit bytes │ 32─bit words │ ├────────────────────┼────────────────────┼──────── ──────┼──────────────┤ │ 0 │ 00000000000000 00 │ ┌──────────┐ │ ┌──────────┐ │ │ │ │ └─────────┘ │ │ │ │ │ 1 │ 0000000000000001 │ ┌──────────┐ │ │ │ │ │ │ │ └─────────┘ │ │ │ │ │ 2 │ 0000000000000010 │ ┌──────────┐ │ │ │ │ │ │ │ └─────────┘ │ │ │ │ │ 3 │ 0000000000000011 │ ┌──────────┐ │ │ │ │ │ │ │ └────────┘ │ └──────────┘ │ │ 4 │ 00000000000001 00 │ ┌──────────┐ │ ┌──────────┐ │ │ │ │ └─────────┘ │ │ │ │ │ 5 │ 0000000000000101 │ ┌──────────┐ │ │ │ │ │ │ │ └─────────┘ │ │ │ │ │ 6 │ 0000000000000110 │ ┌──────────┐ │ │ │ │ │ │ │ └─────────┘ │ │ │ │ │ 7 │ 0000000000000111 │ ┌──────────┐ │ │ │ │ │ │ │ └────────┘ │ └──────────┘ │ │ 8 │ 00000000000010 00 │ ┌──────────┐ │ ┌──────────┐ │ │ │ │ └─────────┘ │ │ │ │ │ 9 │ 0000000000001001 │ ┌──────────┐ │ │ │ │ │ │ │ └─────────┘ │ │ │ │ │ 10 │ 0000000000001010 │ ┌──────────┐ │ │ │ │ │ │ │ └─────────┘ │ │ │ │ │ 11 │ 0000000000001011 │ ┌──────────┐ │ │ │ │ │ │ │ └────────┘ │ └──────────┘ │ │ ... │ │ │ │ └────────────────────┴────────────────────┴──────── ──────┴──────────────┘
推荐阅读
- import - 将csv文件导入py
- python - Asyncpg:KeyError '0'
- c# - 如何将 BIM 360 文件的内容作为文件流读取并将其写入另一个流
- angular - 角度测试未通过 100% 否则未采用路径
- spock - 2 期待 Spock 中的区块?
- mysql - 在 MySQL 存储过程中使用 SELECT...FOR UPDATE 的 ResultSet
- javascript - 电子导航(单页导航)
- r - 创建一个新的 1 和 0 列作为计算 R 中唯一值的方法
- javascript - 在javascript中将响应从服务器流式传输到本地文件?
- node.js - 我如何将文件引用存储在 MongoDB 中去 FireBase