【问题标题】:Segmentation Fault: 11 for small C program on macOS 10.14 Mojave分段错误:macOS 10.14 Mojave 上的小型 C 程序为 11
【发布时间】:2018-09-29 14:54:39
【问题描述】:

我不确定为什么在尝试编译这个小 C 文件时会收到 Segmentation Fault: 11

#include <stdio.h>

#define MIN  97
#define MAX  122
#define DIFF 32

int main()
{
  int c = EOF;
  int i, j;
  int arr[MAX - MIN];

  for(i=MIN; i<=MAX; i++)
    arr[i] = 0;

  while((c = getchar()) != EOF) {
    if(c >= MIN)
      ++arr[c];
    else
      ++arr[c + DIFF];
  }

  for(i=MIN; i<=MAX; i++) {
    printf("|%c|", i);
    for(j=1; j<=arr[i]; j++)
      putchar('-');
    putchar('\n');
  }
  return 0;
}

我正在使用 Apple 的内置 cc,它只是 Clang/Apple LLVM 10.0.0

这个文件在 macOS 10.13.6 上编译得很好,我在 10.14 上编译任何其他 C 文件/程序没有任何问题;这只是一个文件。从我初学者的角度来看,这似乎是操作系统的一个错误。

编辑:这个程序是我在here找到的 K&R 练习中稍作修改的示例

【问题讨论】:

  • 我想你想要++arr[c-MIN],一方面。
  • “我觉得这是操作系统的错误。”不,它几乎总是你的程序中的一个错误。
  • 我没有编写程序 - it's an example someone else wrote 用于 K&R 书籍练习。在升级到 macOS 10.14 之前,它编译并运行得很好。
  • 我觉得这是操作系统的一个错误 非常非常非常糟糕的印象。像这样的简单程序几乎永远不会发现操作系统错误,尤其是在一个已经存在了很长时间的操作系统中,即使不是数十亿,也有数亿用户。
  • 您看到的是“未定义的行为”。请参阅stackoverflow.com/questions/7961067/… 了解有关该问题的一个问题。

标签: c segmentation-fault


【解决方案1】:

用这条线

int arr[MAX - MIN];

...您正在创建一个由 25 (122 - 97) 个整数组成的数组。有效的数组索引为 0 ... 24。

首先,由于每个数组单元格专用于一个小写字母,因此数组应该有 26 个单元格。

然后,用这个语句(以及接下来的语句):

for (i = MIN; i <= MAX; i++) arr[i] = 0;

...您正在写入不存在的数组单元arr[97]arr[122],覆盖程序堆栈的其他部分。这就是你得到分段错误的原因。

【讨论】:

  • 感谢您的回复。当我复制/粘贴代码时,我注意到了 25 的数组,但无论出于何种原因,它之前运行良好。我将数组更改为 26,但仍然收到分段错误。
  • @rootbeersoup 你忽略了我的最后一句话。主要问题是您从不写入分配的数组,而是将其写入堆栈的另一部分,这会覆盖宝贵的数据(如返回地址)并触发段错误。
  • @rootbeersoup 该任务可以使用 26 的数组大小来完成,但不能使用编写的代码。查看for 循环,他们假设MAX 是一个有效的数组索引。数组大小必须至少为 123。我建议你找一个不同的例子来学习,这个例子很糟糕。
  • @xhienne 好的,所以在玩过它之后,一个 123 或更高的数组可以让程序运行良好而没有错误。如果我将数组设置为 122 或更低(不确定此处允许的最低值),程序会运行,但在按下 CTRL+D 时会抛出 Abort trap: 6。我猜这不是惯用的,这似乎是我糟糕程序的一种解决方法。对吗?
  • @Blastfurnace 谢谢,这对我来说很有意义。感谢您的建议,我很困惑,因为该程序之前对我来说运行良好并假设代码很好。
猜你喜欢
  • 2019-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-29
相关资源
最近更新 更多