C 指针:试图通过添加大量数字来取消引用指针时发生读取访问冲突

C 指针:试图通过添加大量数字来取消引用指针时发生读取访问冲突,c,visual-studio,pointers,pointer-arithmetic,C,Visual Studio,Pointers,Pointer Arithmetic,我正在尝试更多地探索指针,下面是我正在尝试的一段示例代码 这是有效的: int *arth, art; art = 100; arth = &art; printf("arth address is %p arth+1 value is %d", arth, *(arth + 1)); printf("arth address is %p arth+1 value is %d", arth, *(arth + 1000)); 现在,如果我尝试向arth添加一个大的数字,我会得到读取访

我正在尝试更多地探索指针,下面是我正在尝试的一段示例代码

这是有效的:

int *arth, art;
art = 100;
arth = &art;
printf("arth address is %p arth+1 value is %d", arth, *(arth + 1));
printf("arth address is %p arth+1 value is %d", arth, *(arth + 1000));
现在,如果我尝试向arth添加一个大的数字,我会得到读取访问冲突

这不是:

int *arth, art;
art = 100;
arth = &art;
printf("arth address is %p arth+1 value is %d", arth, *(arth + 1));
printf("arth address is %p arth+1 value is %d", arth, *(arth + 1000));
错误:

int *arth, art;
art = 100;
arth = &art;
printf("arth address is %p arth+1 value is %d", arth, *(arth + 1));
printf("arth address is %p arth+1 value is %d", arth, *(arth + 1000));
引发异常:读取访问冲突。 arth为0xC9C5964。发生

询问:
有人能解释为什么这在添加1时有效,而在添加1000时无效,因为这调用了未定义的行为

未定义的行为是指程序可能意外行为。在您的情况下,它可能在第一个代码段和第二个代码段中工作。或者,在今天,这两种情况可能根本不起作用。明天可以。在你的机器里它可能会工作,在我的机器里…也许不会!阅读更多关于

您正在访问指针不应该访问的内存

当您添加1时,您可能(不)幸运,您可以访问程序拥有的内存,因此您可以从警方(操作系统)处逃脱

当您添加1000时,您将退出程序的段,导致段错误或访问冲突(您可以这么说!)

可视化:

您的行为就像
arch
指向一个数组,当
array[i]
有效时,
array[i+1]
也有效(假设i+1不大于或等于数组的大小)

然而,
arch
只指向一个变量,不多也不少



C允许你整天做指针算术,但是你要对结果负责。在您的情况下,这两个增量在语法等方面都是有效的,但会调用未定义的行为,这是一个逻辑错误(可以说会导致无效的运行时)。

arth
指向
int
的单个实例。将任何非零值添加到
arth
,然后取消引用该新指针值将读取原始
int
边界之外的内存位置。这引起了人们的注意

对于未定义的行为,任何事情都可能发生。您的程序可能会崩溃,可能会输出奇怪的结果,或者看起来工作正常。您没有在
*(arth+1))
案例中崩溃,但在
*(arth+1000))
案例中崩溃就是一个例子


程序没有崩溃并不意味着它没有做错什么。

Arth指向一个整数,但Arth+1没有指向代码中定义的任何地方,Arth+1000也没有


实际上,C允许您通过内存分配递增指向一个元素的指针,因此技术上允许arth+1,但arth+1000不允许。arth+1000的行为尚未定义,因此任何事情都可能发生。在您的情况下,这是一个错误。

*(arth+1000)与arth[1000]相似,并且(arth+1)等于arth[1]。(arth+1000)您尚未在内存中分配或初始化任何空间,因此编译器将抛出未定义的行为,并且没有此类分配的数据到该位置。

这两个都是无效的,无论它是什么*(arth+1)或(arth+1000),因为您正在访问根本未分配的内存。它可能由于未定义的行为而工作。使用valgrind运行并检查valgrind日志,无论是*(arth+1)还是*(arth+1000),它都将报告无效读取。添加任何与指针相关的代码时,请始终运行valgrind。

没有太多需要解释的内容?取消对bodged-a-lot指针的引用会导致内存管理硬件中断,因此会显示错误消息。看不到任何问题。您是否希望得到其他结果?具体来说是什么?这两个都是非法访问,因此未定义,所以不是我问一个人为什么“工作”毫无意义有人没有。
如果行为未定义,任何事情都有可能发生。您的程序可能会崩溃,可能会输出奇怪的结果,或者看起来工作正常。
谢谢,我想我得到了什么是未定义的行为
所以技术上允许arth+1
谢谢,如果我理解正确,我认为即使arth+1也未定义RTH+1是技术上的不允许,但您没有在arth+1分配任何内容,因此尝试取消引用它仍然是未定义的行为lol。我也没有初始化arth+1,因此总之,尝试遵从一些未初始化的内容会导致UB