Reputation: 29
My program crashes when malloc(x*sizeof(char))
, x
< limit of fgets
, despite buffer == NULL
check.
In my example, when x is 1, and limit of what fgets can take is 100, and user types eg. 5 characters from keyboard (fgets() call), program crashes, returning some random like: 19284791298 value.
My problem: instead of crashing, I would prefer if it returned NULL.
Reason: I upload my code to my univ's linux platform that tests program's reaction to heap limit change to 0 and to 130, when my program is written to return NULL if user's input exceeds 100 characters. I don't quite understand how the environment changes memory limit to 0 and 130 and what exactly is changed, but even though, I noticed my program in CodeBlocks, windows 10, crashes in this situation described here (x < stdin input) despite checking buffer == NULL
.
I wish buffer == NULL
check could somehow work and prevent the crash.
If x
was 100, and size
was 1 (instead of 1 and 100), my program would return NULL and set err_code to 1.
I'm thinking: I can't do with x the same "if" statement I did for strlen(buffer), because... to check how long input written to buffer is, firstly I'd need to check length of what was written to this buffer?!.
printf("Insert data: ");
char *buffer = (char* )malloc(1*sizeof(char));
if (buffer == NULL)
return NULL;
int size=100;
if (fgets(buffer, size, stdin)!=NULL) {
if (strlen(buffer)>(unsigned)(size-2)) { //'\0' and enter are 2 chars
free(buffer);
*err_code=1;
return NULL;
}
//... here goes some sscanf to fill struct fields, etc.
}
In other words. A bit condensed what I think may lead to understanding of my problem:
Is there a way to end program returning something, instead of letting it crash in such situation? A way to make if(buffer == NULL)
work? Why doesn't this check work?
I'm unfamiliar with linux. When I see a comment in report I get, that linux sets (heap?) limit to 0 or 130 (when testing my program), does it mean I can replicate the problems it encounters by setting my x
to 0
, 130
? (in the part malloc(x*sizeof(char))
.
Upvotes: 0
Views: 167
Reputation: 47915
When you call fgets
, you must tell it how big the destination buffer is. You are not just telling it the maximum number of characters you want it to read, so that it can automatically allocate that much space, or anything like that. You are telling it what the size of the buffer already is, and you are telling fgets
that it absolutely must not read any more characters than that, otherwise the buffer will overflow. (fgets
never does any allocating of its own.)
So when you say
char *buffer = (char* )malloc(1*sizeof(char));
followed by
int size=100;
fgets(buffer, size, stdin)
you have lied. You have allocated a buffer of size 1, and you have told fgets
that the buffer is of size 100. So fgets
will read up to 99 characters, and store them into buf
, and in most cases this will badly overflow the buffer.
What you want to do is something more like this:
int size = 100;
char *buffer = (char* )malloc(size*sizeof(char));
if (buffer == NULL)
return NULL;
if (fgets(buffer, size, stdin)!=NULL) {
...
Also, although it doesn't have anything to do with your problem, there is no need to multiply by sizeof(char)
when calling malloc
(because sizeof(char)
is 1 by definition), and in C, there is no need to cast the return from malloc
into the destination pointer type, either. I would just call
char *buffer = malloc(size);
Upvotes: 4
Reputation: 139
In your code, you have allocated buffer as a single byte array
char *buffer = (char* )malloc(1*sizeof(char));
int size=100;
if (fgets(buffer, size, stdin)!=NULL) {
In the fgets, you would want to read into buffer an input of 100 bytes. When the input is read into the buffer it goes beyond the allocated area and overwrites other data. Because of this, your program crashes,
Upvotes: 1