这段C代码会导致分段错误吗?

3
int *i;
*i=123;

3
总是没有为变量i分配内存。 - Sajad Bahmani
3
并非总是这样,指针变量 i 的值完全是随机的,它有可能指向一个有效的内存地址。 - Alon
8
更不用说,代码可能在没有内存分段概念的机器上运行,因此无法产生分段错误。 - anon
根据Neil的建议,@SjB目前可能会导致分段错误,而且你的答案在未来可能是不正确的,因为如果C语言语义被更改以防止这种情况导致分段错误或编译失败,则可能无法实现。 - Larry Watanabe
在最好的情况下,它会产生一个段错误。如果没有,它将导致更难调试的问题。 - Graphics Noob
如果您拥有http://dspace.dial.pipex.com/town/green/gfd34/art/中描述的系统之一,那么结果比分段错误更加“有趣”! - Alok Singhal
6个回答

30

是的。没有分配内存来存储值123

就像初始化变量int不能保证为0一样,int*也不能保证是安全的地址。

这也可能会导致数据损坏。


1
虽然不保证会导致段错误,但它可能会偶然指向可写位置。 - Evan Teran

29

它可以,但也可能做任何事情——它表现出C标准所谓的“未定义行为”。


2
它甚至可以抹掉你的硬盘。虽然不太可能,但确实有可能发生。 - Adam Rosenfield
3
可能性并不像它看起来那样小。我以前经常在运行新组装的代码之前将软盘从我的旧Z80 CP/M计算机中取出,以防止发生这种情况! - anon
3
就 C 语言而言,它可能会擦除您的硬盘驱动器。现在,如果一个进程执行未定义的行为,则仍然受操作系统安全规则的约束,因此发生这种情况的几率很小。不过,如果你最近使用了 "sudo" 命令... - Jason Orendorff
3
除非您只是为了沙盒测试C编译器而创建了用户帐户,否则您的用户权限很可能足以删除您在硬盘上关心的任何内容,即使它无法完全擦除。 - Steve Jessop
请记住,编译器允许为未定义的行为生成任何内容,因此开始一场乒乓球游戏是被允许的! - Tim Williscroft

3

是的


2

32位操作系统的大致概率:

  • 触发硬件异常的几率:99.9995%
  • 破坏程序状态的几率:0.0005%
  • 意外命中正确的内存位置的几率:20亿分之1

仅估算数量级。 仅适用于发布版本。 如果确实破坏了程序状态,则它会一致地爬升到接近100%。 好的编译器可以使调试版本中的硬件异常几率达到100%。 获取好的编译器。


是的,我将被初始化为一个随机值。但是谁说必须是线性分布的呢? - R. Martinho Fernandes
1
我认为你的意思是“均匀分布”。但如果该代码在调用一个将指针留在该堆栈位置的函数后立即执行,那么很有可能它指向有效的内存。 - Adam Rosenfield

2

是的,您发布的代码可能会导致分段错误。您有一个未初始化的指针(不指向任何已知位置),然后将其用于存储某些内容。这个“东西”去哪了?好问题,没有一致的答案。

您需要初始化该指针。例如:

int target = 0;
int *i = ⌖ 

printf("target=%d\n", target);
*i=123; 
printf("target=%d\n", target);

我希望这能有所帮助。


1

int *i; 这段代码分配了一个指针的内存空间,但是这个变量没有被初始化,所以它的值是随机的。然后你对它进行解引用操作,得到一个随机地址,并在内存中写入数据,但是 1) 你不知道这个地址是哪里 2) 这个地址可能不属于你的内存空间。你可以通过初始化来解决这个问题,例如 int * i = ( int* ) malloc( sizeof(int) )


2
C语言没有new运算符。 - Daniel A. White
你说得对,是我的错。有一个叫做malloc的函数。我会修复它。 - Gaim
2
在C语言中,将void*转换为int *是不必要的,也是不良实践。使用int *i = malloc(sizeof(int));就足够了。 - Chinmay Kanchi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接