尝试使用scanf中的数据时出现SEGFULT?
我真的很难理解是什么导致了这个问题,我真的很想了解幕后发生了什么,让这个问题发生。下面的代码旨在获取最大长度为99个字符的字符串,将其放入一个名为word的变量中,然后读取长度;稍后我将根据字符串中的字符数量重新分配分配给它的内存,但现在我只想能够获得输入。以下是代码段:尝试使用scanf中的数据时出现SEGFULT?,c,segmentation-fault,scanf,C,Segmentation Fault,Scanf,我真的很难理解是什么导致了这个问题,我真的很想了解幕后发生了什么,让这个问题发生。下面的代码旨在获取最大长度为99个字符的字符串,将其放入一个名为word的变量中,然后读取长度;稍后我将根据字符串中的字符数量重新分配分配给它的内存,但现在我只想能够获得输入。以下是代码段: char* word = malloc(100); printf("Enter a string:\n"); int x = scanf("%s", &word); printf("Length = %d", x);
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,因为我需要在以后realloc,以避免使用比以后需要的内存更多的内存。在您的代码中
int x = scanf("%s", &word);
应改为
int x = scanf("%99s", word); //99 chars to be scanned - at max - see note below
由于word
已经是指向char
的指针,因此
- 是
%s
- 指向您刚才分配的内存
fscanf()
系列的C11
,第§7.21.6.2章
s
[…]如果不存在l
长度修饰符,则相应的参数应为a
指向字符数组的初始元素的指针,该元素的大小足以接受
序列和一个将自动添加的终止空字符。[……]
注意:当有疑问/困惑时,务必检查数据类型
的类型为word
——正确且预期的类型char*
属于&word
-类型错配char**
- 始终检查库函数是否成功执行/返回。(
,malloc()
等),然后再使用结果scanf()
- 始终限制扫描大小,以防止过长的输入导致缓冲区溢出
- 问题就在这里:
intx=scanf(“%s”和&word)代码>。不要盲目地将和与scanf一起使用。确实,您应该将地址传递给scanf
,但这里您传递的是word
的地址。变量word
本身就是一个地址(或者更确切地说,包含一个地址)。您希望从该地址开始写入数据
放下&
。使用intx=scanf(“%s”,单词)代码>查看您的代码片段:
char* word = malloc(100);
printf("Enter a string:\n");
int x = scanf("%s", &word);
问题就在我引用的最后一行scanf()
需要一个指向%s
的char
数组的指针。但是,使用运算符的地址(&
)会获取指针的地址,因此您将给scanf()
一个指向指针的指针word
。这是未定义的行为,scanf()
只会覆盖指针word
(从而破坏它)——可能会发生其他奇怪的事情。简单的解决方案:删除&
尽管如此,上面的代码并不是全部错误,下面一行:
int x = scanf("%s", word);
还具有未定义的行为。这是因为您永远无法保证输入的前99个字符中会有空格,因此此代码可能会使缓冲区溢出。对于scanf()
到字符串的转换,始终使用字段宽度,如下所示:
int x = scanf("%99s", word);
最后,对于固定且相当小的内存量,实际上不需要动态分配它(而且我看不到您会按需要调用free()
)。只需将第一行替换为
char word[100];
您仍然可以用相同的方式编写其余的代码。在大多数上下文中,数组的标识符的计算结果是指向第一个元素的指针,例如,当将其传递给函数时。问题在于此语句int x=scanf(“%s”和&word)
。您已经声明了char*word=malloc(100)
,这意味着它是一个字符数组。您可以将语句修改为int x=scanf(“%s”,word)
(不带&
)。
检查下面的示例代码:
传递word
本身为数组的第一个元素提供地址,以存储读取的值
话虽如此,如果您需要的内存量在编译时就已经知道,那么最好静态分配内存,如下所示:
char-word[100]
要读取指定数量的字符,请使用表达式scanf(“%s”),
。在您的情况下,它将是:
scanf(“%99s”,word)
这里提供的示例代码:可能重复的int x=scanf(“%s”和&word);
->int x=scanf(“%s”,word);
@ChrisTurner这是一个很好的链接,但是你确定这是一个重复吗?@PaulR我也有一个问题,为什么不需要在malloc(100*sizeof(char))中编写呢
我们需要一个100字符长的字符串吗?@Alansizeof(char)
被标准定义为1
。你能帮我理解为什么需要这样做吗?这是因为字符串在C中的工作方式(字符数组)或者?这实际上是有道理的,所以如果我已经将变量定义为指针,我不需要在scanf函数中使用-,太好了!@PixelRain是的,我想你明白了,@PixelRain你可能应该读一读你的C教科书中关于指针的章节。