为什么野指针持有零地址而不是garabge地址?

问题描述 投票:-1回答:1

我一直试图在不使用sizeof()的情况下找到一个特定的数据类型如 "int "的大小,并找到了这个。

#include<stdio.h>

int main() {

    int *ptr;   /*Declare a pointer*/
    printf("Size of ptr = %d\n",ptr);
    ptr++;

    printf("Size of ptr = %d\n",ptr);
    return 0;
}

这将返回int的正确大小。怎么做?wild指针不是应该包含垃圾地址而不是零吗?如果它包含0,它和NULL指针有什么不同,因为NULL是(void*)0?

c++ c pointers
1个回答
3
投票

由于 ptr 是未初始化的,它的值是不确定的,访问它的值会给出未定义的行为。 有点讽刺的是,"未定义 "的含义,被C和C++标准定义为类似 "这个标准并不约束会发生什么 "的意思。

初学者经常错误地认为这意味着它必须包含一个 "垃圾值",或者是一个 "野生指针",或者是 "在这里添加一些丰富多彩的描述",但事实根本不是这样。

"值是不确定的 "或 "访问该值时的行为是未定义的 "的含义是,从访问该值的代码中允许任何行为。

访问值是必要的,可以打印它、增量它,或者(在指针的情况下)取消引用它(访问指针值所标识的地址的内容)。

访问该值的代码的行为是未定义的。 给予打印的值为零。42或一个 "垃圾值 "都是正确的结果。 然而,同样,结果也可能意味着没有输出,或者是不可取的行为,比如重新格式化硬盘。 如果代码被重复执行,行为甚至可能会随着时间的推移而改变。 或者它可能是100%可重复的(对于特定的编译器、特定的操作系统、特定的硬件等)。

实际上,具有未定义行为的代码在程序测试过程中没有任何故障的迹象,但后来在客户的计算机上安装和执行程序时,却会造成一些讨厌的、可见的、但非预期的影响,这是非常常见的。 这往往会导致客户脾气暴躁,开发者可能无法复制的bug报告,以及开发者试图修复缺陷的压力。

因此,试图解释为什么未定义的行为会导致一些特定的结果(例如打印一个零值)是毫无意义的。


0
投票
  • "为什么野生指针持有零地址而不是garabge地址?" 它们没有。垃圾意味着任何东西;甚至是零。 一些编译器可能有一个特殊的功能来解决默认初始化(但据我所知,它不是由标准要求的) - 检查生成的代码。

  • "这将为int返回正确的大小。" 不,它没有。它只是打印了一些垃圾,这些垃圾 恰好是你要找的.

你可能正在寻找类似于下面的代码;它的工作原理是基于 相邻地址之差. 注意到 sizeof 是一个编译时的操作符,而下面的代码是在运行时计算大小的(然而,编译器可能会用一个常数代替它)。

    int* p = 0;
    int sizeof_int = (char*)(p + 1) - (char*)p; // works with uninitialized p, too

-2
投票

如果是零,那么第二个打印结果将是int的大小,因为指针的增量是随着指针的大小而增加的。

比如说,你的例子中,如果你得到的指针是0,那么第二次打印的大小将是int,因为指针的增量是随着指针的大小而递增的。

char *x = 0;
x++; //x=1

int *y = 0;
y++; //y=4

在你的例子中,如果你在第一次打印的时候得到了0, 那就和你把它初始化为NULL是一样的,但是... ... 不可能永远都是零的。.

© www.soinside.com 2019 - 2024. All rights reserved.