使用 *(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 位系统中重叠。注意可能这个词,没有保证。
#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
|?|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 位系统中重叠。注意可能这个词,没有保证。