我编写了类似下面代码的内容,并且我能够在增加它之后为新地址分配一个值,但是无法打印此值run time error
,同时在为该位置指定一个值之后指向,指针值变为14.任何人都知道发生了什么?
为位置本身赋值后,为什么指针值本身会更改为14?
增加指针值后我没有收到任何错误!
#include <stdio.h>
int main()
{
int x = 10;
int *ptr = &x;
printf("%x\n",ptr); // ptr value
ptr++; //No ERROR !!
printf("%x\n",ptr); //ptr value +4 bytes no error!!!
*ptr = 20;
printf("%x\n",ptr); //ptr=14
printf("%x\n",*ptr); // run time error happens here only
return 0;
}
答案 0 :(得分:2)
这是未定义的行为。当您增加指针变量时,它指向一个超过变量x
(在系统中超过4个字节)的变量。但是你取消引用它。首先,您更改的内存不是由您分配的。而且它不是已经分配的位置(如数组的一部分等)。访问它是未定义的行为。
您可以再次将其分配给任何可能的地址。但是取消引用它将是未定义的行为,以防它指向的内存地址无效。
来自标准 6.3.2.3
一元
*
运算符表示间接。如果操作数指向a 功能,结果是功能指示符;如果它指向一个 对象,结果是指定对象的左值。如果是操作数 类型为''pointer to type''
,结果类型为type
。 如果是 无效值已分配给指针,行为 一元*
运算符未定义
答案 1 :(得分:0)
当你执行ptr++
时,它指向&#34;一个元素&#34;过去x
。这是允许的,因为在这种情况下x
被视为大小为1的数组,并且允许指针指向一个元素超过数组的末尾。您也可以随后打印该指针的值。
然而,你可以做的是取消引用一个指向一个元素的指针。这会调用undefined behavior。在这种情况下,该行为表现为指针具有意外值和随后的崩溃。
话虽如此,这里可能发生了什么。
ptr
最有可能放在x
内存之后,所以在ptr++
之后,ptr
指向了自己。因此*ptr = 20;
具有将ptr
设置为20的效果。打印的值14以十六进制表示,与20十进制相同。这解释了打印的价值。
然后您尝试打印*ptr
,在这种情况下说&#34;在地址0x14&#34;处打印int
值。这很可能不是一个有效的地址,因此尝试阅读它会导致崩溃。
但是,您无法依赖此行为。您可以添加额外的printf
或使用不同的优化设置进行编译,并且观察到的行为会发生变化。