scanf上的段故障不在所有系统上

时间:2014-03-27 13:42:54

标签: c segmentation-fault scanf

此代码在我的Ubuntu,Gentoo,Windows 7 64位(MinGW gcc非常旧的版本3.6)上导致seg故障,但在我朋友的Windows 7 64位(MinGW gcc 4.6)上没有。

这里是代码(实际上我无法理解这对我朋友的系统有什么用处,str显然没有分配)。

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

int main() {
 char *str, *str1, *str2;

 printf(">>> ");
 scanf("%­s", str);

 for(str1 = str, str2 = strlen(str)+str-1; str2>str1; ++str1, --str2) {
   *str1 ^= *str2;
   *str2 ^= *str1;
   *str1 ^= *str2;
 }

 printf("<<< %­s", str);

 return 0;
}

提前谢谢。

编辑:他刚给我发了他的.exe,实际上每次都有效,我发了大约20次。我没有言语。

2 个答案:

答案 0 :(得分:1)

此代码调用未定义的行为。一旦调用了UB,那么所有的赌注都会被取消。什么事情都可能发生。编译器到编译器的行为可能会有所不同,甚至在同一编译器的不同版本上,您可能会得到不同的结果,无论是预期的还是意外的,分段错误,程序崩溃等等。

答案 1 :(得分:0)

它可能适用于某些系统,有时候,如果你很幸运,初始化指针中包含的垃圾值指向一些有效的内存。但是,即使它没有崩溃,你也可以写一些其他进程内存,这可能会改变它们的工作方式。

我曾经有过一次有趣的经历,我正在研究一个加密程序,但是我把检查搞砸了,找到了缓冲区的结尾。代码加密内存直到它崩溃,并在间隔中,它找到了Windows存储屏幕位图的缓冲区,我最终得到了一个很好的人工制品。

我猜这种幸运的上下文只发生在32位系统上,或者如果ASLR被禁用。

你正在使用MinGW,如果我记得,默认情况下它既没有64位编译,也没有启用ASLR,所以如果你的朋友有大约4 GB的RAM并且他的电脑运行了一段时间,它可以解释你得到了什么。 我想你的Windows 7和他的主要区别在于RAM的数量和你正在运行的程序。