【问题标题】:How do you locate and fix a segfault?如何定位和修复段错误?
【发布时间】:2014-04-04 16:27:42
【问题描述】:

我一直在寻找互联网和 SO,并试图找到如何检测和修复段错误。我经常遇到这个错误,我只能在谷歌上找到,所以这是一个内存问题(这个答案很有帮助:https://stackoverflow.com/a/3200536/3334282)。我想知道导致它的糟糕编程是什么,以便我可以避免它。

我最近的例子是尝试学习如何使用 fgets()。

FILE *text;
char array[100];

fopen("text.txt", "r");
fgets(array, 100, text);

printf("%s\n", array);

fclose(text);

这会返回 8181 分段错误(核心转储)。

【问题讨论】:

  • text = fopen("text.txt", "r")
  • 谢谢@Exceptyon 和 Joachim 我不知道它需要初始化,为什么会这样?它修复了错误,但我仍然想知道如何避免它们。
  • 当您尝试访问未经授权的内存时会发生段错误。这里你创建了一个 FILE 指针,但是你没有分配它,你需要使用 fopen 来做这件事。如果您不知道,我建议您从头开始修改 c,抱歉。无论如何,为了避免一般的段错误,请在有问题的代码周围设置断点并在执行时查看变量值。

标签: c segmentation-fault fgets


【解决方案1】:

在这种情况下很明显:你在哪里初始化text

未初始化的局部变量具有不确定的值,使用未初始化的局部变量会导致未定义的行为,而可能会导致崩溃。


对于问题标题中表述的更通用的问题,这更难,因为很多事情都可能导致分段错误。使用未初始化的指针可能会导致它,使用NULL 指针肯定会导致崩溃。超出分配内存的范围写入(如数组的超出范围写入)可能会覆盖其他数据,从而导致其他指针意外更改其值,这也可能导致崩溃。

简而言之,如果使用不当,使用指针会导致分段错误。

但是,许多未定义行为的情况,例如您的代码中的行为,可以通过启用更多警告(例如 GCC 的 -Wall 标志)并修复这些警告来避免。虽然警告在技术上不是错误,但它们通常表明您在做一些可疑的事情。再次以您的代码为例,通过将 -Wall 添加到您的 GCC 命令行,您会收到有关使用未初始化变量 text 的警告。

【讨论】:

    【解决方案2】:

    Segmentation fault 在您尝试使用操作系统未分配给您的进程的内存时发生。一些常见的情况是当您使用指针时。

    当您尝试释放未分配给您的内存时(当指针具有垃圾值时),例如您的情况 text 未初始化并且您尝试关闭它。

    当您尝试释放已释放的内存时。

    【讨论】:

      【解决方案3】:

      即使您展示了使用动态分配的语言(如 Perl 或 Python)的源代码,变量 text 也没有被赋值。所以,你在大多数语言中都有同样的问题。防止此类问题的一种方法是检查变量。

      您可以通过使用printf 或使用调试器来打印它们。在您的情况下,printf-ing text 会显示一个对您来说没有意义的数值,并且在您执行打开时会出现段错误。

      您遇到了段错误,因为您的程序正在尝试访问特权内存;至少它对运行程序的进程具有特权。如果您将text 分配给fopen 语句的返回值

      text = fopen("text.txt", "r");

      那么文本要么为 NULL,要么包含text.txt 的文件句柄。这是因为您只是使用了text's 随机值,所以您得到了段错误。

      【讨论】:

        猜你喜欢
        • 2020-02-22
        • 2012-09-04
        • 1970-01-01
        • 2019-10-25
        • 1970-01-01
        • 2017-06-04
        • 2022-11-21
        • 2012-09-25
        相关资源
        最近更新 更多