在符合 c ansi 标准的 scanf 中使用 malloc
Is using malloc within scanf compliant to c ansi standard
我想读取用户的输入并保存。我现在所拥有的确实有效,但我需要知道 scanf 在为输入分配内存之前首先分配变量 "length" 是否合法(遵循 ansi 标准 - c90),
或者如果它只是编译器的一个怪癖。
#include <stdio.h>
int main()
{
char* text;
int length = 0;
scanf("%s%n", text = malloc(length+1), &length);
printf("%s", text);
return 0;
}
这不会如您所愿。
在您调用 malloc
时,length
的值仍然为 0,因此您只分配了一个字节。 length
直到 scanf
returns 之后才更新。因此,任何非空字符串都将写入已分配缓冲区的边界,调用 undefined behavior.
虽然不完全相同,但您可以使用 getline
,假设您 运行 在 POSIX 系统上比如Linux。此函数读取一行文本(包括换行符)并为该行分配 space。
char *text = NULL;
size_t n = 0;
ssite_t rval = getline(&text, &n, stdin);
if (rval == -1) {
perror("getline failed");
} else {
printf("%s", text);
}
free(text);
除了另一个答案中提到的滥用 scanf
的明显问题外,这也不遵循任何 C 标准:
#include <stdio.h>
...
text = malloc(length+1)
由于您没有在找到 malloc
的地方包含 stdlib.h
,C90 将假定函数 malloc
具有 int malloc(int);
的形式,这当然是无稽之谈。
然后当您尝试将 int
(malloc 的结果)分配给 char*
时,您违反了 C90 6.3.16.1 的约束,即简单赋值规则。
因此您的代码不允许干净地编译,但编译器必须给出诊断消息。
您可以通过升级到标准 ISO C 来避免此错误。
其他人很好地解释了问题
I want to read the input of a user and save it
要添加并实现 OP 的目标,可以使用类似的代码
int length = 255;
char* text = malloc(length+1);
if (text == NULL) {
Handle_OOM();
}
scanf("%255s%n", text, &length);
// Reallocate if length < 255 and/or
if (length < 255) {
char *t = realloc(text, length + 1);
if (t) text = t;
} else {
tbd(); // fail when length == 255 as all the "word" is not certainly read.
}
如果过多的输入被认为是敌对的,以上将是一个简单的方法。
我想读取用户的输入并保存。我现在所拥有的确实有效,但我需要知道 scanf 在为输入分配内存之前首先分配变量 "length" 是否合法(遵循 ansi 标准 - c90), 或者如果它只是编译器的一个怪癖。
#include <stdio.h>
int main()
{
char* text;
int length = 0;
scanf("%s%n", text = malloc(length+1), &length);
printf("%s", text);
return 0;
}
这不会如您所愿。
在您调用 malloc
时,length
的值仍然为 0,因此您只分配了一个字节。 length
直到 scanf
returns 之后才更新。因此,任何非空字符串都将写入已分配缓冲区的边界,调用 undefined behavior.
虽然不完全相同,但您可以使用 getline
,假设您 运行 在 POSIX 系统上比如Linux。此函数读取一行文本(包括换行符)并为该行分配 space。
char *text = NULL;
size_t n = 0;
ssite_t rval = getline(&text, &n, stdin);
if (rval == -1) {
perror("getline failed");
} else {
printf("%s", text);
}
free(text);
除了另一个答案中提到的滥用 scanf
的明显问题外,这也不遵循任何 C 标准:
#include <stdio.h>
...
text = malloc(length+1)
由于您没有在找到 malloc
的地方包含 stdlib.h
,C90 将假定函数 malloc
具有 int malloc(int);
的形式,这当然是无稽之谈。
然后当您尝试将 int
(malloc 的结果)分配给 char*
时,您违反了 C90 6.3.16.1 的约束,即简单赋值规则。
因此您的代码不允许干净地编译,但编译器必须给出诊断消息。
您可以通过升级到标准 ISO C 来避免此错误。
其他人很好地解释了问题
I want to read the input of a user and save it
要添加并实现 OP 的目标,可以使用类似的代码
int length = 255;
char* text = malloc(length+1);
if (text == NULL) {
Handle_OOM();
}
scanf("%255s%n", text, &length);
// Reallocate if length < 255 and/or
if (length < 255) {
char *t = realloc(text, length + 1);
if (t) text = t;
} else {
tbd(); // fail when length == 255 as all the "word" is not certainly read.
}
如果过多的输入被认为是敌对的,以上将是一个简单的方法。