我一直在寻找互联网和SO,并试图找到如何检测和修复segfault。我经常会遇到这个错误,我在谷歌上能找到的只有内存问题(这个答案帮助很大:https://stackoverflow.com/a/3200536/3334282)。我想知道是什么糟糕的编程导致了它,这样我就可以避免它
我最近的例子是试图学习如何使用fgets()。
FILE *text;
char array[100];
fopen("text.txt", "r");
fgets(array, 100, text);
printf("%sn", array);
fclose(text);
这返回8181分段故障(核心转储)。
在这种情况下,很明显:在哪里初始化text
?
未初始化的局部变量有一个不确定的值,使用未初始化的本地变量会导致未定义的行为,会导致崩溃。
对于问题标题中使用的更通用的问题,这更难,因为很多事情都会导致分段错误。使用未初始化的指针可能会导致崩溃,使用NULL
指针肯定会导致崩溃。在已分配内存的边界外写入(如数组的边界外),可能会覆盖其他数据,使其他指针意外更改其值,这也可能导致崩溃。
简而言之,如果使用不当,使用指针可能会导致分段错误。
然而,许多未定义行为的情况,如代码中的行为,可以通过启用更多警告(如GCC的-Wall
标志)并修复这些警告来避免。虽然警告在技术上不是错误,但它们通常是你做了可疑事情的标志。再次以您的代码为例,通过将-Wall
添加到GCC命令行,您将收到关于使用未初始化变量text
的警告。
Segmentation fault
发生在您尝试使用操作系统未分配给进程的内存时。一些常见的情况是当您使用指针时。
当你试图释放一个没有分配给你的内存时(当指针有垃圾值时),比如你的案例text
没有初始化,你试图关闭它。
当您试图释放已释放的内存时。
即使您显示了来自使用动态分配的语言(如Perl或Python)的源代码,变量text
也没有赋值。所以,在大多数语言中都有同样的问题。防止此类问题的一种方法是检查变量。
您可以通过使用printf
打印它们或使用调试器来完成此操作。在您的情况下,printf
和text
将显示一个对您来说没有意义的数值,并且在执行open时会得到segfault。
您得到了一个segfault,因为您的程序正试图访问特权内存;至少它对运行程序的进程具有特权。如果您将text
分配给fopen
语句的返回值
text = fopen("text.txt", "r");
则文本将为NULL或者将包含CCD_ 15的文件句柄。这是因为你只是使用text's
随机值,你得到了segfault。