尝试使用scanf中的数据时出现段错误?

时间:2018-07-26 09:38:38

标签: c segmentation-fault scanf

对于可能导致此问题的原因,我实在感到非常不安,而且我真的很想了解幕后发生的事情。下面的代码旨在获取最大长度为99个字符的字符串,将其放入名为word的变量中,然后读取该长度;稍后,我将根据字符串中的字符数量重新分配分配给它的内存,但是现在我只希望能够获得输入。这是代码段:

char* word = malloc(100);
printf("Enter a string:\n");
int x = scanf("%s", &word);
printf("Length = %d", x);
printf("Word is %s", word);

使用时会发生这种情况:

Enter a string:
123
1
Segmentation Fault

这是怎么回事?为什么这不起作用?我以为用malloc分配内存会给它足够的空间,然后scanf会将我的话放到变量中?我需要使用malloc,因为我需要稍后重新分配以不使用比以后需要更多的内存。

4 个答案:

答案 0 :(得分:3)

在您的代码中

 int x = scanf("%s", &word);

应更改为

 int x = scanf("%99s", word); //99 chars to be scanned - at max - see note below

因为word已经是指向char的指针

  • %s的预期参数类型
  • 指向您刚刚分配的内存。

针对C11家庭,引用fscanf(),第§7.21.6.2章

  

s

     

[...]如果不存在l长度修饰符,则相应的自变量应为   指向足够大的字符数组的初始元素的指针,可以接受   序列和终止的空字符,这些字符将自动添加。 [....]

注意:如有疑问/困惑,请务必检查数据类型。

  • word的类型为char *-正确和预期的类型
  • &word的类型为char **。 -键入误匹配

话虽如此,几点提示

  • 始终检查库函数是否成功执行/返回。 (malloc()scanf()等)。
  • 始终限制扫描的大小,以防止由于过长的输入而导致缓冲区溢出。

答案 1 :(得分:3)

查看您的代码段:

char* word = malloc(100);
printf("Enter a string:\n");
int x = scanf("%s", &word);

问题在我引用的最后一行中。 scanf()期望指向char的某个%s数组的指针。但是使用 address-of 运算符(&)会获得指针的地址 ,因此,您要给scanf()的指针指向指针改为word。这是未定义的行为scanf()只会覆盖指针word(从而破坏指针)-可能会发生其他奇怪的事情。简单的解决方案:删除&

仍然不是上面代码的所有错误所在,如下行:

int x = scanf("%s", word);

也具有未定义的行为。那是因为您永远不能保证输入的前99个字符中会有空格,因此此代码可以溢出缓冲区。始终将字段宽度用于scanf()到字符串的转换,如下所示:

int x = scanf("%99s", word);

最后,对于固定且相当少量的内存,实际上并不需要动态分配它(我不认为您会按要求调用free())。只需将第一行替换为

char word[100];

您仍然可以用相同的方式编写其余代码。在大多数情况下,例如,数组的标识符评估为指向第一个元素的指针。将其传递给函数时。

答案 2 :(得分:1)

问题出在这里:int x = scanf("%s", &word);。请勿盲目地将&scanf一起使用。的确,您应该将地址传递到scanf,但是在这里,您正在传递地址word。变量word本身就是一个地址(或更确切地说,包含一个地址)。您希望从该地址开始写入数据。

拖放&。使用int x = scanf("%s", word);

答案 3 :(得分:0)

此语句 responses: 200: description: "successful operation, return the definition of the resource type in the body" schema: $ref: '#/definitions/MyResponseSchema' definitions: MyResponseSchema: type: object properties: name: type: string schema: type: object properties: ... example: # <------------ name: Element schema: properties: id: type: string extension: type: array items: $ref: '#/definitions/Extension' 存在问题。您已声明int x = scanf("%s", &word),这意味着它是一个字符数组。您可以将语句修改为char* word = malloc(100)(无int x = scanf("%s", word))。 在https://www.tutorialspoint.com/c_standard_library/c_function_scanf.htm

中查看示例代码

传递&本身会为数组的第一个元素提供地址,以存储读取的值。

如果要在编译时知道所需的内存量,最好将静态分配为:

word

要读取指定数量的字符,请使用表达式char word[100]。在您的情况下,将是:

scanf("%<count>s", <stringVariable>

此处提供示例代码:https://en.wikipedia.org/wiki/Scanf_format_string