使用 *(p+1) 将值 20 分配给内存中的下一个地址并且打印不会产生输出

Assigning value 20 to next address in the memory using *(p+1) and printing does not produce output

 #include <stdio.h>
 #include <stdlib.h>

 int main(void)
 {
    int a=10 ;
    int *p;
    p = &a;
    *(p+1) = 20;
    printf("The value at (p+1) is %d\n",*(p+1));

    return 0;
  }

我正在尝试进行一些指针运算并尝试实现代码。我正在尝试使用 *(p+1) 将值 20 分配给内存中的下一个地址,并使用 printf 语句打印它,但我的代码没有产生任何输出。为什么会这样?

'a' 是一个普通整数,您无法浏览元素,因为没有元素。

它只是一个指向变量的普通指针。

 #include <stdio.h>
 #include <stdlib.h>

 int main(void)
 {
    int a[10];
    *(a+1) = 20;
    printf("The value at (p+1) is %d\n",*(a+1));

    return 0;
  }

我想这就是你想要的

在下面:

int a=10 ;

a 被声明和初始化时,10 被放置在内存中创建它的位置,如下面的内存描述所示:

|?|10|?|...
  ^
  a

然后是报表

int *p;
p = &a;

创建一个指针p,将指针设置为指向同一位置

|?|10|?|...
  ^
  p

在语句中*(p+1) = 20;

*(p + 1) 引用内存中您的进程不拥有的位置,超出 a

的 1 个内存位置
    |?|10|?|...
         ^

尝试在那里赋值会调用 undefined behavior.

这样看,*(p + 1) 等同于 p[1] 这意味着你正在寻找 a[1]a 不是数组,a[1] 在你的程序中不存在,你不能在该内存位置读取或写入,我们真的不知道那里有什么,这就是为什么你的程序遭受 undefined behavior.

这实际上以一种非常可疑的方式打动了我。我在代码中遇到分段错误。我们有不同的结果。

首先,谁保证p + 1是偶数内存?它很可能是 0x00。不是开玩笑!你可能在一个奇怪的系统上,其中内存反向工作,如果 &a 是 0x04,那么 a + 1 就是 0x00。不存在内存由于某种原因倒退的系统,但它可能会发生。我不认为该标准强制执行与此相关的任何内容(如果我错了请纠正我)。这只会造成混乱,难怪没有人尝试过。

其次,谁向您保证 p + 1 没有被使用过?编译器可能正在使用它,它经常这样做。

第三,谁向您保证拾取一些您尚未分配的内存甚至可以工作?分配内存基本上就是保留内存,如果你不这样做,就不能保证任何事情都有效。想象一辆公共汽车。如果您不预定座位,则无法保证您一定能坐到。

那么会发生什么?未定义的行为!基本上,如果达到这种情况,那么编译器可以编写代码,向总统发送死亡威胁,并让你参加恐怖组织的民兵训练,编译器仍然可以称自己为“ISO/IEC 9899:2018 兼容”。除非标准中有一个引人注目的“编译器不能插入恶意代码”短语。我没有检查过。是的,这就是为什么你不应该使用模糊的编译器。开个玩笑,基本上任何事情都有可能发生,上帝,只有上帝知道会发生什么。甚至编译器,你,ISO 都不知道会发生什么。这就是为什么“未定义的行为”如此可怕的原因。不要用记忆做奇怪的事情。

顺便说一句,让这个特别有趣的是 &p,对于大多数编译器来说,在 32 位系统上与 p + 1 是一样的。它可能在 64 位系统中重叠。注意可能这个词,没有保证。