简体   繁体   中英

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.

#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. length isn't updated until after scanf returns. 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. 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:

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

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.

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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