C 使用指针访问零位置

C 使用指针访问零位置,c,pointers,memory,memory-management,C,Pointers,Memory,Memory Management,为什么我们不能访问例如位置0(0),100(100), 内存中有二百(200)个 例: 引用C11,第章 …如果为指针指定了无效值,则一元*运算符的行为是未定义的 引用C11,第章 ..一元*运算符取消引用指针的无效值包括空指针、地址.. 重点矿山 而且 引用C11,第章 值为0的整型常量表达式或转换为类型void*的此类表达式称为空指针常量。如果将空指针常量转换为指针类型,则生成的指针(称为空指针)保证与指向任何对象或函数的指针进行不相等比较 因此,您试图取消对空指针的引用,该指针的行为已明确

为什么我们不能访问例如位置0(0),100(100), 内存中有二百(200)个

例:


引用
C11
,第章

如果为指针指定了无效值,则一元*运算符的行为是未定义的


引用
C11
,第章

..
一元*运算符取消引用指针的无效值包括空指针、地址
..

重点矿山

而且


引用
C11
,第章

值为
0
的整型常量表达式或转换为类型
void*
的此类表达式称为空指针常量。如果将空指针常量转换为指针类型,则生成的指针(称为空指针)保证与指向任何对象或函数的指针进行不相等比较

因此,您试图取消对空指针的引用,该指针的行为已明确表示为标准未定义

正如正确指出的那样,除了
*(char*)NULL
是未定义的行为外,还有另一个原因说明这在任何健全的系统上都不起作用:链接器和/或系统内核通常会做出特殊规定,以确保在地址零处永远不会映射任何可访问内存

因此,任何取消引用空指针的尝试都会触发硬件异常,因为根本没有硬件可以访问的内存。此硬件异常会直接向系统内核发出有关该情况的警报,系统内核通常会通过使用分段错误终止进程来作出反应


这样做的原因是,意外地取消引用空指针是一个非常常见的错误,并且通常不建议让进程在进入未定义行为的领域后继续执行可能有害的操作。这一进程的立即崩溃通常被视为较小的罪恶。它使空指针访问的调试变得非常容易:如果进程是在调试器下执行的,调试器将直接将程序员指向试图取消引用空指针的那一行。程序员要做的唯一一件事就是弄清楚为什么那一行试图去引用空指针,以及实际的逻辑错误在哪里。这比其他形式的未定义行为要容易得多,因为症状可能出现在程序中一些完全不相关的位置。

因为对于大多数现代多处理操作系统,操作系统的内存管理子系统小心地确保第一页(通常为1024或4096字节)内存类型无效,无法读取或写入(或执行)。对于这些系统,典型的响应是分段故障(可能是堆芯转储)。在糟糕的过去,DEC VAX系统允许您读取(和写入?)内存位置0;因此,为VAX开发的程序在其他任何地方都不一定运行良好。另请参见)。您已经回答了我的问题!感谢you@JonathanLeffler虽然我同意您的评论,但访问地址0(所有位为零)和将整数0强制转换为地址之间存在差异。虽然标准明确禁止第二个,但标准允许第一个,但实现不允许。@AjayBrahmakshatriya:我不确定我是否理解你的说法。指针常数为零是空指针。给定的机器可能会对空指针使用不同的(不是所有位零)表示,但在源代码级别,如果指定空指针常量,则使用“所有位零”值,编译器的任务是使其在编译所针对的硬件上正常工作。C程序(在o/s内核的很小一部分之外)处理虚拟地址。在典型的桌面系统中,在(虚拟)页面0中读取或写入会导致分段错误。
void main() {
    int* a;
    a = 0;
    printf("what is inside position o %d",*a);

}