我不太清楚这个说法:
int **ptr;
printf (" %p \n", &( *( *(ptr + 1) + 4) ) );
确实,我无法解释自己为什么在运行时没有出现段错误,因为它不应该能够使用*
带有返回值的数字的操作数*(ptr + 1)
。
出于性能原因,C 是一种旨在在某种程度上反映硬件性质的语言。在大多数情况下,它也是静态编译的,这需要提前编译和链接整个代码库。因此,它不一定会提前检查所有可能的人为错误。好的可能会在这里发出警告,但不会产生错误。
在运行时,您的代码正在执行的是调用未定义的行为。正如其他人在评论中提到的那样,未定义的行为并不意味着崩溃。事实上,有时崩溃是在这种情况下可能发生的最理想的行为,因为调试器可以立即为您提供有关问题所在的信息。在不太理想的情况下,该程序似乎运行良好,除非偶尔,当满月出来时,行为会发生不规律的变化。它可能因编译器而异,从构建设置到构建设置,从平台到平台,所以你真的想尽可能地避免它们。
在实践中,当您尝试访问指针以进行读访问时,段错误的发生频率往往低于写访问,因为操作系统从某些内存部分读取的规则通常比写入它更宽松。甚至对另一个程序的内存的写访问通常也受到保护,而如果地址本身超出有效的物理范围,读访问可能只会导致段错误。