1

我不明白为什么这段代码不会引发分段错误:

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

int main (void){
    char* c;
    strncpy(c,"Gustave",10);
    return 0;
}

而这个确实:

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

void aux (void){
    char* c;
    strncpy(c,"Gustave",10);
}

int main (void){
    aux();
    return 0;
}

对我来说,这两个应该造成分段错误,因为我们正在访问未分配的内存。

另一个问题是:

为什么这会引发总线错误,而不是分段错误:

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

void aux (void){
   char* const c = "Bonjour";
   strncpy(c,"BonjourBonjour",20);
}

int main (void){
    aux();
    return 0;
}
4

3 回答 3

4

没有什么好理解的。你所有的片段都有未定义的行为,就语言而言,这就是结束。

编译器和运行时没有义务对您编写的内容执行任何特定操作。编译器可以拒绝完全编译,或者编译一个完全不同的程序。不保证会出现段故障、总线错误或任何其他特定于操作系统的行为。

取决于运气,未初始化的变量中有哪些随机垃圾,堆栈在该点的布局方式等,代码甚至可能执行您想要的操作,并且错误可能会在很长一段时间内未被检测到,从而导致最糟糕的情况之一寻找各种错误。

编写正确的代码,打开所有警告,使用不同的编译器和优化设置进行编译,并使用诸如valgrind尝试确保代码干净的工具。

于 2014-05-27T08:45:18.617 回答
0

如果代码 1 没有段错误,那是因为你有 "luck" :字符串可能写在分配给你的程序的内存中,而不是第二个代码中。

于 2014-05-27T08:42:26.273 回答
0

它将产生未定义的行为,因为正如您正确指出的那样,您正在尝试复制到未分配的内存中,但在我的 IDE 中,这两种情况都会产生段错误。当您的处理器甚至无法尝试请求的内存访问时,就会发生编辑总线错误。访问不属于您的进程的内存时会发生分段错误

于 2014-05-27T08:43:58.237 回答