简体   繁体   English

在scanf中使用malloc符合c ansi标准

[英]Is using malloc within scanf compliant to c ansi standard

I want to read the input of a user and save it. 我想阅读用户的输入并保存。 What i have now does work but i need to know if its legit (following ansi standard - c90) that scanf is first assigning the variable "length" before it allocates memory for the input, or if its just a quirk of the compiler. 我现在有什么工作,但我需要知道它是否合法(遵循ansi标准 - c90)scanf在为输入分配内存之前首先分配变量“length”,或者它只是编译器的一个怪癖。

#include <stdio.h>
int main()
{
    char* text;
    int length = 0;
    scanf("%s%n", text = malloc(length+1), &length);

    printf("%s", text);

    return 0;
}  

This will not work as you expect. 不会像你期望的那样工作。

At the time you call malloc , length still has the value 0, so you're only allocating one byte. 在调用malloclength仍然具有值0,因此您只分配一个字节。 length isn't updated until after scanf returns. scanf返回之前, length不会更新。 So any non-empty string will write past the bounds of the allocated buffer, invoking undefined behavior . 因此,任何非空字符串都将写入已分配缓冲区的边界,从而调用未定义的行为

While not exactly the same, what you can do is use getline , assuming you're running on a POSIX system such as Linux. 虽然不完全相同 ,但你可以做的是使用getline ,假设你在一个POSIX系统上运行,比如Linux。 This function reads a line of text (including the newline) and allocates space for that line. 此函数读取一行文本(包括换行符)并为该行分配空间。

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);

Apart from the obvious problem with misuse of scanf addressed in another answer, this doesn't follow any C standard either: 除了在另一个答案中解决了滥用scanf的明显问题之外,这也不遵循任何C标准:

#include <stdio.h>
...
text = malloc(length+1)

Since you didn't include stdlib.h where malloc is found, C90 will assume that the function malloc has the form int malloc(int); 由于你没有包含stdlib.h ,其中找到malloc ,C90将假设函数malloc的形式为int malloc(int); which is of course nonsense. 这当然是胡说八道。

And then when you try to assign an int (the result of malloc) to a char* , you have a constraint violation of C90 6.3.16.1, the rules of simple assignment. 然后,当您尝试将一个int (malloc的结果)分配给char* ,您的约束违反了C90 6.3.16.1,即简单赋值的规则。

Therefore your code is not allowed to compile cleanly, but the compiler must give a diagnostic message. 因此,不允许您的代码干净地编译,但编译器必须提供诊断消息。

You can avoid this bug by upgrading to standard ISO C. 您可以通过升级到标准ISO C来避免此错误。

Issues well explained by others 其他人解释的问题很好

I want to read the input of a user and save it 我想阅读用户的输入并保存

To add and meet OP's goal, similar code could do 要添加并满足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.
}

The above would be a simple approach if excessive input was deemed hostile. 如果过度投入被认为是敌对的,那么上述将是一种简单的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM