【问题标题】:GCC `scanf` segmentation faultGCC`scanf`分段错误
【发布时间】:2013-06-09 01:08:11
【问题描述】:

我在玩 C 和 scanf 函数时遇到了这个我似乎无法弄清楚的奇怪错误。给定以下代码:

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

typedef struct {
  int a;
} sample;

void fn(sample *s) {
  char command;
  scanf("%[abc]", &command);
  printf("Read: %c\n", command);
  printf("In the sample function:, %i\n", s->a);
}

int main() {
  sample *s = malloc(sizeof(sample));
  s->a = 4;

  printf("Before sample function: %i\n", s->a);
  fn(s);
  printf("After sample function: %i\n", s->a);

  return 0;
}

这似乎是段错误。输出:

$ ./sample
Before sample function: 4
a
Read: a
In the sample function:, 4
Segmentation fault (core dumped)

我使用 gdb 并在结构上附加了一个watch,似乎在scanf 函数内部,似乎“修改”了结构?这很奇怪,因为即使在示例函数“fn”中的scanf 之后,它也能够很好地打印出结构字段。但是,一旦从fn 返回并跳回到main,它会在尝试打印相同的信息时出现段错误?

有趣的是,如果您将scanf 更改为scanf("%c\n", &amp;command);(没有字符集),它似乎可以正常工作。作为记录,我使用的 gcc 版本是 4.7.2,我正在编译代码:gcc -O0 -o sample sample.c。

我唯一的想法是 gcc 可能不支持字符集?我不知道。只是想知道是否有其他人可以解决这个问题?

【问题讨论】:

  • gcc (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2 它适用于 gcc -O0 -o sample sample.c

标签: c gcc struct scanf


【解决方案1】:

scanf("%[abc]", &amp;command);

写入一个字符串而不是单个字符。字符串的尾随空字符正在您的程序中写入&amp;command + 1。

你应该传递给scanf 类似的东西:

command 与 command 是:

char command[2];

【讨论】:

  • 啊。谢谢!这实际上很有意义。不敢相信我没有想到这一点。
  • 不客气!另请注意,如果您将多个字符传递给scanf,您将溢出缓冲区。要进行错误恢复,您应该使用sscanf 而不是scanf 来查看fgets。
  • 如果您不介意,再问一个简单的问题,有什么理由可以在其他版本的 GCC 或 clang 上工作?
  • 您的程序调用了未定义的行为,由于未定义未定义,它可能在周六工作,但在周一失败。
  • 您还应该使用scanf("%1[abc]", &amp;command) 将字符串限制为单个字符,这样它就不会溢出两个字符的缓冲区...
猜你喜欢
  • 1970-01-01
  • 2013-12-22
  • 1970-01-01
  • 1970-01-01
  • 2020-12-15
  • 2015-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多