相同的源代码但不同操作系统的结果不同

时间:2015-12-22 05:35:18

标签: c pointers dereference pointer-arithmetic

我正在学习指针。我在教程中看到了这段代码示例。我尝试了但是它给出了不同的教程结果。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int i = 5;
    int myInt = 7;
    int *pointer = &i;
    printf("%i\n", *(pointer + 1));

    return 0;

}
    在Windows机器上
  • ,输出为2686740

  • 在linux机器上,输出为7。

这是什么原因?

4 个答案:

答案 0 :(得分:1)

要详细说明现有答案,我想补充说明。

在您的代码中,iint变量。您将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;一个在窗户上。教训是:不要写这样的代码;)