我正在学习指针。我在教程中看到了这段代码示例。我尝试了但是它给出了不同的教程结果。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i = 5;
int myInt = 7;
int *pointer = &i;
printf("%i\n", *(pointer + 1));
return 0;
}
,输出为2686740
在linux机器上,输出为7。
这是什么原因?
答案 0 :(得分:1)
要详细说明现有答案,我想补充说明。
在您的代码中,i
是int
变量。您将i
的地址指定给pointer
。精细。然后,你要做的是,递增指针(地址),然后尝试取消引用它。
现在,与代码中的语句相比,
printf("%i\n", *(pointer + 1));
引用C11
标准,第6.5.6章,添加运算符
[....]如果两个指针 操作数和结果指向同一个数组对象的元素,或者指向最后一个数组对象的元素 数组对象的元素,评估不得产生溢出;否则, 行为未定义。 如果结果指向一个超过数组对象的最后一个元素的那个,那么 不得用作被评估的一元
*
运算符的操作数。
基本上,通过执行此操作,您尝试访问未分配给您的进程的某些内存,从而调用undefined behavior。
UB的输出, undefined 。
答案 1 :(得分:0)
您正在将指针算法运行到未为该指针/引用分配的区域中,因此它未定义。它可以在编译器希望的情况下实现。
实际的原因是在Linux上,变量my int位于地址&amp; i + 1,而在Windows上......它在其他地方
答案 2 :(得分:0)
内存(本例中是堆栈)就像这样
[ i ][ something else ....
^ ^
^ pointer+1
pointer
做
int *pointer = &i;
printf("%i\n", *(pointer + 1));
你显示一个int,即来自pointer+1
的{{1}}的内存空间被读作sizeof(int)
,这是编译器不希望你做的事情,那个空间是“未知”。所以Windows可能会显示X,Linux也可能会显示X,显示其他内容甚至崩溃......
这是未定义的行为。
答案 3 :(得分:0)
我认为代码正在对可能存在或可能不存在的内存布局做出假设。假设是:堆栈是线性的,变量的存储方式与源中声明的完全相同。这有点暗示您假设编译器不进行任何优化。
在Windows上尝试以下操作:(i)关闭编译器的所有优化,(ii)或以调试模式运行。行为可能会或可能不会切换到&#34;期望&#34;一个在窗户上。教训是:不要写这样的代码;)