C编程,指针运行时间错误
C programming , pointers run time error
我编写了类似于以下代码的代码,在增加新地址后我能够为其分配一个值,但无法打印该值 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;
}
这是未定义的行为。当您递增指针变量时,它指向变量 x
之后的一个(在您的系统中过去 4 个字节)。但是然后你取消引用它。首先,您更改的内存不是您分配的。而且它也不是已经分配的位置(如数组的一部分等)。访问它是未定义的行为。
同样,您可以将其分配给任何可能的地址。但是,如果它指向的内存地址无效,取消引用将是未定义的行为。
来自标准 6.3.2.3
The unary *
operator denotes indirection. If the operand points to a
function, the result is a function designator; if it points to an
object, the result is an lvalue designating the object. If the operand
has type ''pointer to type''
, the result has type type
. If an
invalid value has been assigned to the pointer, the behavior of the
unary *
operator is undefined
当您执行 ptr++
时,它指向 "one element" 过去 x
。这是允许的,因为 x
在这种情况下被视为大小为 1 的数组,并且允许指针指向数组末尾后面的一个元素。您也可以随后毫无问题地打印该指针的值。
然而,您不能做的是取消引用指向末尾后一个元素的指针。这会调用 undefined behavior。在这种情况下,该行为表现为指针具有意外值和随后的崩溃。
话虽如此,这可能是发生了什么。
ptr
很可能在内存中紧跟在 x
之后,所以在执行 ptr++
之后,ptr
指向它自己。所以 *ptr = 20;
具有将 ptr
设置为 20 的效果。打印的值 14 是十六进制的,与十进制的 20 相同。这解释了打印的值。
然后您尝试打印 *ptr
,在本例中为 "print the int
value at address 0x14"。这很可能不是有效地址,因此尝试读取它会导致崩溃。
但是你不能依赖这种行为。您可以添加额外的 printf
或使用不同的优化设置进行编译,观察到的行为将会改变。
我编写了类似于以下代码的代码,在增加新地址后我能够为其分配一个值,但无法打印该值 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;
}
这是未定义的行为。当您递增指针变量时,它指向变量 x
之后的一个(在您的系统中过去 4 个字节)。但是然后你取消引用它。首先,您更改的内存不是您分配的。而且它也不是已经分配的位置(如数组的一部分等)。访问它是未定义的行为。
同样,您可以将其分配给任何可能的地址。但是,如果它指向的内存地址无效,取消引用将是未定义的行为。
来自标准 6.3.2.3
The unary
*
operator denotes indirection. If the operand points to a function, the result is a function designator; if it points to an object, the result is an lvalue designating the object. If the operand has type''pointer to type''
, the result has typetype
. If an invalid value has been assigned to the pointer, the behavior of the unary*
operator is undefined
当您执行 ptr++
时,它指向 "one element" 过去 x
。这是允许的,因为 x
在这种情况下被视为大小为 1 的数组,并且允许指针指向数组末尾后面的一个元素。您也可以随后毫无问题地打印该指针的值。
然而,您不能做的是取消引用指向末尾后一个元素的指针。这会调用 undefined behavior。在这种情况下,该行为表现为指针具有意外值和随后的崩溃。
话虽如此,这可能是发生了什么。
ptr
很可能在内存中紧跟在 x
之后,所以在执行 ptr++
之后,ptr
指向它自己。所以 *ptr = 20;
具有将 ptr
设置为 20 的效果。打印的值 14 是十六进制的,与十进制的 20 相同。这解释了打印的值。
然后您尝试打印 *ptr
,在本例中为 "print the int
value at address 0x14"。这很可能不是有效地址,因此尝试读取它会导致崩溃。
但是你不能依赖这种行为。您可以添加额外的 printf
或使用不同的优化设置进行编译,观察到的行为将会改变。