C编程,指针运行时出错

C编程,指针运行时出错,c,pointers,runtime,C,Pointers,Runtime,我编写了类似以下代码的代码,在增加新地址后,我能够为其分配一个值,但无法打印此值运行时错误,也在为指针指向的位置分配一个值后,指针值更改为14。有人知道发生了什么吗 为什么指针值本身在为位置本身赋值后更改为14 我没有得到任何错误后,增加指针值太多 #include <stdio.h> int main() { int x = 10; int *ptr = &x; printf("%x\n",ptr); // ptr value

我编写了类似以下代码的代码,在增加新地址后,我能够为其分配一个值,但无法打印此值
运行时错误
,也在为指针指向的位置分配一个值后,指针值更改为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;
}
#包括
int main()
{
int x=10;
int*ptr=&x;
printf(“%x\n”,ptr);//ptr值
ptr++;//没有错误!!
printf(“%x\n”,ptr);//ptr值+4字节无错误!!!
*ptr=20;
printf(“%x\n”,ptr);//ptr=14
printf(“%x\n”,*ptr);//仅在此处发生运行时错误
返回0;
}

这是未定义的行为。当您递增指针变量时,它指向变量
x
(在您的系统中超过4个字节)后面的一个。但随后你取消了对它的引用。首先,您更改的内存不是由您分配的。而且它不是一个已经分配的位置(如数组的一部分等)。访问它是未定义的行为

同样,您可以将其分配到任何可能的地址。但如果它指向的内存地址无效,则取消引用它将是未定义的行为

来自标准

一元
*
运算符表示间接寻址。如果操作数指向 函数,结果是函数指示符;如果它指向一个 对象,结果是指定该对象的左值。如果操作数 具有类型
“指向类型的指针”
,结果具有类型
type
如果是 为指针指定了无效值,该指针的行为 一元
*
运算符未定义


这是未定义的行为。当您递增指针变量时,它指向变量
x
(在您的系统中超过4个字节)后面的一个。但随后你取消了对它的引用。首先,您更改的内存不是由您分配的。而且它不是一个已经分配的位置(如数组的一部分等)。访问它是未定义的行为

同样,您可以将其分配到任何可能的地址。但如果它指向的内存地址无效,则取消引用它将是未定义的行为

来自标准

一元
*
运算符表示间接寻址。如果操作数指向 函数,结果是函数指示符;如果它指向一个 对象,结果是指定该对象的左值。如果操作数 具有类型
“指向类型的指针”
,结果具有类型
type
如果是 为指针指定了无效值,该指针的行为 一元
*
运算符未定义


当您执行
ptr++
操作时,它将“一个元素”指向过去的
x
。这是允许的,因为在这种情况下,
x
被视为大小为1的数组,并且允许指针指向数组末尾的一个元素。您也可以随后毫无问题地打印该指针的值

但是,您不能做的是取消引用一个指向结束后一个元素的指针。这引起了我的注意。在本例中,该行为表现为指针具有意外值和随后的崩溃

话虽如此,以下是可能发生的情况

ptr
最有可能放在内存中的
x
之后,因此在执行
ptr++
之后,
ptr
指向自身。所以
*ptr=20
具有将
ptr
设置为20的效果。打印的值14是十六进制的,与十进制的20相同。这解释了打印的值

然后您尝试打印
*ptr
,在本例中显示“打印地址0x14处的
int
值”。该地址很可能不是有效地址,因此尝试读取该地址会导致崩溃


然而,你不能依赖这种行为。您可以添加一个额外的
printf
或使用不同的优化设置进行编译,观察到的行为将发生变化。

当您执行
ptr++
时,它会指向“一个元素”超过
x
。这是允许的,因为在这种情况下,
x
被视为大小为1的数组,并且允许指针指向数组末尾的一个元素。您也可以随后毫无问题地打印该指针的值

但是,您不能做的是取消引用一个指向结束后一个元素的指针。这引起了我的注意。在本例中,该行为表现为指针具有意外值和随后的崩溃

话虽如此,以下是可能发生的情况

ptr
最有可能放在内存中的
x
之后,因此在执行
ptr++
之后,
ptr
指向自身。所以
*ptr=20
具有将
ptr
设置为20的效果。打印的值14是十六进制的,与十进制的20相同。这解释了打印的值

然后您尝试打印
*ptr
,在本例中显示“打印地址0x14处的
int
值”。该地址很可能不是有效地址,因此尝试读取该地址会导致崩溃


然而,你不能依赖这种行为。您可以添加额外的
printf
或使用不同的优化设置进行编译,观察到的行为将发生变化。

一旦移动指针,指针将不再指向任何有效位置。没有错误,只有未定义的行为。。您的代码有6个未定义行为的位置一旦移动指针,它就不再指向任何有效位置。没有错误,只有未定义的行为。。哟