C编程,指针运行时错误

问题描述 投票:0回答:2

我编写了类似下面代码的东西,并且我能够在增加它之后为新地址分配一个值,但是无法打印此值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;
}
c pointers runtime
2个回答
0
投票

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

然而,你不能做的是取消引用一个指向一个元素的指针。这会引发undefined behavior。在这种情况下,该行为表现为指针具有意外值和随后的崩溃。

话虽如此,这可能发生了什么。

ptr很可能是在x记忆之后,所以在做了ptr++之后,ptr指向自己。所以*ptr = 20;具有将ptr设置为20的效果。打印的值14是十六进制,与20十进制相同。这解释了打印的价值。

然后你试图打印*ptr,在这种情况下说“打印地址0x14处的int值”。这很可能不是一个有效的地址,因此尝试阅读它会导致崩溃。

但是,您无法依赖此行为。您可以添加额外的printf或使用不同的优化设置进行编译,并且观察到的行为会发生变化。


2
投票

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

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

从标准6.3.2.3

一元*算子表示间接。如果操作数指向函数,则结果是函数指示符;如果它指向一个对象,则结果是指定该对象的左值。如果操作数的类型为''pointer to type'',则结果为type。如果为指针指定了无效值,则unary *运算符的行为未定义

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