由于某些原因,指针地址为NULL

时间:2018-10-04 16:57:10

标签: c pointers

这是一个显示指针地址的简单程序:

#include <stdio.h>

int main(void)
{
    int *a;
    int *b;

    printf ("address of a : %p, the address of b : %p\n", a, b);
    return (0);
}

所以输出是这样的:

address of a : 0x7fff537b1ad8, the address of b : 0x0

我的问题是:为什么变量b的地址存储器无效,而变量a没有

4 个答案:

答案 0 :(得分:1)

两者指针均指向无效内存。仅仅因为指针指向看似有效的内存位置,并不意味着它在程序上下文中有效。

为了详细说明,a指向的内存位置未分配给您的程序,因此从您的应用程序的角度来看,它是无效的内存。任何读取或写入的尝试都将引起未定义的行为。

换句话说,绝对不能保证b将保留一个NULL值,它也可以具有其他看似正确但无效的内存地址。无论它们指向的内存位置如何,它们都是无效的。

答案 1 :(得分:1)

您实际上并不是在打印指针的地址。您正在打印这些指针的。而且由于这些变量尚未初始化,因此它们的值不确定。

您需要使用address-of运算符获取其地址:

printf("address of a : %p, the address of b : %p\n", (void *)&a, (void *)&b);

请注意,这是需要强制转换为void *的少数情况之一。

答案 2 :(得分:1)

本地变量具有自动存储持续时间(超出范围,可能分配了堆栈)。

要使用自动存储持续时间(未使用其地址)访问未初始化的变量,则会调用未定义的行为。做任何事情都会发生。

此外,具有自动存储持续时间的未初始化变量具有不确定值。这意味着它可以包含任何值,包括垃圾,零或有效地址。如果您执行两次程序或在程序中读取两次变量,则不需要两次返回相同的值。在某些外来系统上,如果该值是陷阱表示,则访问具有不确定值的变量会导致未定义的行为。

摘要:由于没有C语言或任何其他人的保证,因此无法说明该代码将做什么。对此类代码的作用进行推理是没有意义的。


作为一个补充说明,地址0与NULL不是同一回事,并且不一定表示空指针。 NULL是空指针常量,不是地址,其值为整数0(void*)0。当将NULL分配给任何类型的指针时,它将创建一个空指针。空指针可以包含任何内部表示形式,例如地址0或其他某个值-C并未指定。

答案 3 :(得分:1)

a [和b]从未被初始化,因此它们可以具有 any 值。它们得到的值恰好是在调用main之前main堆栈帧的相应存储位置中发生的 。也就是说,ab function 作用域变量,因此它们位于函数的堆栈框架中。

在您的情况下,b得到了0x0,而a得到了一个非零值,似乎是有效的,但它不是 。它可以指向程序物理地址空间中的任意位置。我们不知道那是哪里。如果我们从中读取,则它可能在程序的分配/有效/映射的地址空间之外,并且我们也会对此进行段错误。

或者,如果我们写入a所指向的位置,则可能是写入任何位置。因此,我们可能会在随机位置破坏程序数据。这可能不会立即生成异常,但是效果未知。我们可能会覆盖数据段中的值。

这可能会导致程序稍后生成不正确的结果,因为数据段中给定值的值不是静态分配的值。

或者,我们可能破坏了静态分配的 global 内存空间中另一个指针变量中包含的值。稍后,取消引用 指针可能[可能将]产生段错误

它甚至可能指向受保护的内存,例如代码段,这将(再次)生成段错误。