2013-02-12 110 views
-1

我试图在安装在桌面上的Linux上执行以下代码以及安装在虚拟机中的相同的Linux。分段错误结果

#include <stdio.h> 

int main() 
{ 
    int *ptr; 
    printf("%d\n",*ptr); 
    return 0; 
} 

我很惊讶地看到结果 直接在桌面上安装了Linux它提供了“分段错误” 而在安装了虚拟机在Linux上打印一些垃圾值。 任何人都可以请帮我理解为什么是这样吗?

+1

修复这个错误,这个谜将消失。 Buggy代码比正确的代码更难理解。 – 2013-02-12 13:03:50

+1

这被称为“未定义的行为”。你不知道它会做什么。 – ugoren 2013-02-12 13:04:09

+1

解引用未初始化的指针是未定义的行为。 “未定义”意味着任何事情都可能发生。您可能会收到分段错误。或者价值可能是垃圾。或者你的电脑可能爆炸。什么都可以。 – 2013-02-12 13:04:49

回答

1

您的指针未初始化。初始化它象下面这样:

int a = 42; 
int *ptr = &a; 

解引用非初始化指针调用未定义的行为,您的通话printf可以打印一些垃圾或者只是崩溃。

我可以建议你阅读一本关于C编程的书吗?

+0

我知道我们应该初始化指针,因为它不是程序控制中的内存。它可能会或可能不会指向程序的内存映射,所以它的行为将是未定义的。我担心的是为什么它不会在虚拟机上给出分段错误。我试图编译并运行它100次,但它总是给垃圾价值。至少我可能没有发布这个问题,它会给出分段错误。你能否告诉我它与虚拟机有一定的关系?它会是吗? – sandy 2013-02-13 04:38:48

1

因为您正在处理“未定义的行为”。没有定义确切发生的事情。它可能会崩溃,可能会燃烧,或者它可能会做其他预期或意外的事情。

在这种特殊情况下,它可能与ptr从堆栈中获得的值相同 - 它将在虚拟机上有一个有效的内存地址,因此您会得到一些您不知道的随机内存位这是什么。在非虚拟机上,值是不同的[或内存位置不同],并且访问无效内存位置时出现seg-fault。

访问尚未设置为任何内容的指针没有任何用处,但远不保证会崩溃。它可能还会打印该内存地址上的任何内容。

+0

雅,但它总是给一些价值,这将是不变的,但指出的地址得到改变,每次运行。虚拟机中的任何未初始化的内存是否有可能包含某些特定的值。我知道这可能不是真的,但只是作为好奇心问起 – sandy 2013-02-13 04:49:50

+0

虚拟机的行为应该与裸机上的系统相同。但是由于种种原因,事情最终会在内存中出现差异。不,每次都不一定相同 - 现代操作系统有“地址空间随机化”,它将内存中的内容从一次运行转移到另一次运行。 – 2013-02-13 10:37:24

1

您有未初始化的指针。指针就像点与地址一样的整数。自其未初始化以来,它可能包含任何值。因此,在您的VPS上,它可能指向您的进程可以访问的一些有效地址,并且在您的计算机上指向该进程无法访问的未知事物。