Joe*_*oel 119 c c++ memory pointers
在C(或C++)中,指针是特殊的,如果它们的值为零:我建议在释放内存后将指针设置为零,因为这意味着再次释放指针并不危险; 当我调用malloc时,如果它无法获取内存,则返回一个值为零的指针; 我一直用if (p != 0)
它来确保传递的指针是有效的,等等.
但是,由于内存寻址从0开始,因此有效地址不是0吗?如果是这样的话,0如何用于处理空指针?为什么不是负数而是null?
编辑:
一堆好的答案.我将总结在所表达的答案中所说的内容,因为我自己的思想解释了它,并希望如果我误解,社区将纠正我.
就像编程中的其他一切一样,它是一种抽象.只是一个常量,与地址0并不真正相关.C++ 0x通过添加关键字来强调这一点nullptr
.
它甚至不是地址抽象,它是C标准指定的常量,只要它确保它永远不等于"真实"地址,编译器就可以将它转换为其他数字,如果0不是,则等于其他空指针用于平台的最佳价值.
如果它不是抽象,早期就是这种情况,系统使用地址0,程序员不受限制.
我承认,我的负面数字建议是一个狂热的头脑风暴.对地址使用有符号整数有点浪费,如果它意味着除了空指针(-1或其他)之外,值空间在产生有效地址的正整数和刚刚浪费的负数之间均匀分配.
如果任何数字总是可以由数据类型表示,那么它就是0.(也可能是1.我想的是一位整数,如果是无符号则为0或1,或者只有符号的有符号位,或两位整数,将是[-2,1].但是你可以只得0为空,1是内存中唯一可访问的字节.)
还有一些东西在我的脑海里没有得到解决.Stack Overflow问题指向特定固定地址的指针告诉我,即使0表示空指针是抽象,其他指针值也不一定.这导致我发布另一个Stack Overflow问题,我是否可以访问地址零?.
Mic*_*urr 63
2分:
只有源代码中的常量值0是空指针 - 编译器实现可以使用它在运行代码中想要或需要的任何值.某些平台有一个特殊的指针值,该值是"无效的",实现可能会将其用作空指针.C FAQ有一个问题,"说真的,有任何实际的机器真的使用非零空指针,或指向不同类型的指针的不同表示吗?" ,这指出了几个使用0属性的平台是C源代码中的空指针,而在运行时则表示不同.C++标准有一个注释,清楚地表明转换"一个值为零的整数常量表达式总是产生一个空指针,但转换其他碰巧有零值的表达式不需要产生一个空指针".
负值可能与平台一样可用作地址--C标准只需选择一些东西来指示空指针,并选择零.老实说,我不确定是否考虑了其他哨兵价值.
空指针的唯一要求是:
Avi*_* P. 31
从历史上看,从0开始的地址空间始终是ROM,用于某些操作系统或低级中断处理例程,如今,由于一切都是虚拟的(包括地址空间),操作系统可以将任何分配映射到任何地址,因此它可以特别是不在地址0分配任何东西.
rme*_*dor 15
IIRC,"空指针"值不保证为零.编译器将0转换为适合于系统的任何"空"值(实际上它可能总是为零,但不一定是).无论何时将指针与零进行比较,都会应用相同的转换.因为您只能将指针相互比较并与此特殊值0进行比较,所以它使程序员无法了解有关系统内存表示的任何信息.至于为什么他们选择0而不是42或者某些,我猜它是因为大多数程序员从0开始计数:)(另外,在大多数系统上0是第一个内存地址,他们希望它方便,因为在像我所描述的那样练习翻译很少实际发生;语言只允许它们).
AnT*_*AnT 15
你必须误解指针上下文中常数为零的含义.
在C和C++指针中都没有"零值".指针不是算术对象.他们选择具有"零"或"负"等数值或任何具有该性质的数值.因此,关于"指针......具有零值"的陈述根本没有意义.
在C&C++中,指针可以具有保留的空指针值.空指针值的实际表示与任何"零"无关.它绝对适合给定平台.确实,在大多数平台上,空指针值在物理上由实际的零地址值表示.但是,如果在某个平台上,地址0实际上用于某种目的(即您可能需要在地址0处创建对象),则此类平台上的空指针值很可能是不同的.例如,它可以在物理上表示为0xFFFFFFFF
地址值或0xBAADBAAD
地址值.
然而,无论在给定平台上如何呈现空指针值,在代码中您仍将继续按常量指定空指针0
.为了将空指针值分配给给定指针,您将继续使用类似的表达式p = 0
.编译器有责任实现您想要的并将其转换为正确的空指针值表示,即将其转换为将地址值0xFFFFFFFF
放入指针的代码p
.
简而言之,您0
在自己的代码中使用生成空指针值的事实并不意味着空指针值以某种方式与地址相关联0
.将0
您在源代码中使用的仅仅是"语法糖"是绝对没有关系的空指针值"指点"实际的物理地址.
但是,由于内存寻址从0开始,因此有效地址不是0吗?
在某些/多个/所有操作系统上,内存地址0在某种程度上是特殊的.例如,它经常映射到无效/不存在的内存,如果您尝试访问它会导致异常.
为什么不是负数而是null?
我认为指针值通常被视为无符号数:否则例如32位指针只能处理2 GB内存,而不是4 GB.
我的猜测是选择了魔术值0来定义无效的指针,因为可以用更少的指令来测试它。某些机器语言在加载寄存器时会根据数据自动设置零和符号标志,因此您可以通过简单的加载然后测试分支指令来测试空指针,而无需执行单独的比较指令。
(尽管大多数ISA仅在ALU指令上设置标志,但未设置标志。通常,您不会通过计算生成指针,除非在解析C 源代码时在编译器中。但是至少您不需要任意的指针宽度常量来比较。)
在我最初使用的Commodore Pet,Vic20和C64机器上,RAM从位置0开始,因此如果您确实愿意,使用空指针进行读取和写入完全有效。
归档时间: |
|
查看次数: |
34424 次 |
最近记录: |