Reputation: 445
Below is the function which returns a character pointer to a string which was initialized using getc(stdin)
- character by character.
Is there any flaw in memory allocation method? Is this an efficient way when we don't know the size of the string which is going to be entered, if not please explain.
Using getc(stdin)
--will it lead to buffer overflow???()
If I must not use getc(stdin)
, what will help me achieve my goal in a more efficient way?
Code so far:
char *getstring()
{
char *str = NULL, *tmp = NULL;
int size = 0, index = 0;
int ch = -1;
int length=0;
while (ch!=0)
{
ch = getc(stdin);
if (ch == '\n')
{
ch = 0;
}
if (size <= index)
{
size += 15;
tmp = (char*)realloc(str, size);
if (!tmp)
{
free(str);
str = NULL;
}
str = tmp;
}
str[index++] = ch;
}
if(size==index)
{
return str;
}
else if(index<size)
{
length=strlen(str);
tmp = (char*)realloc(str,(length+1));
str[index]='\0';
//cout<<"length:"<<length;
str=tmp;
}
return str;
}
Upvotes: 0
Views: 1279
Reputation: 34585
"Is there any flaw in memory allocation method?" Yes, when the reallocation fails, you free the previous memory pointer, assign NULL
to it, then overwrite it with tmp
, which has the value NULL
, and then plough on using a NULL
pointer.
if (size <= index)
{
size += 15;
tmp = (char*)realloc(str, size);
if (!tmp) // <--- NULL!
{
free(str);
str = NULL;
}
str = tmp; // <--- NULL!
}
str[index++] = ch; // <--- NULL!
But if realloc
fails you have little choice but to abandon the task in hand gracefully.
Also if you allow for the 0-terminator at the same time, you'll save several messy lines of code and another reallocation. And you don't always insert the '\0'
.
if (size <= index+1) // allow room for string terminator
Upvotes: 0
Reputation: 137438
Don't re-invent the wheel: use getline(3)
.
Example (from same URL):
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
int
main(void)
{
FILE *stream;
char *line = NULL;
size_t len = 0;
ssize_t read;
stream = fopen("/etc/motd", "r");
if (stream == NULL)
exit(EXIT_FAILURE);
while ((read = getline(&line, &len, stream)) != -1) {
printf("Retrieved line of length %zu :\n", read);
printf("%s", line);
}
free(line);
fclose(stream);
exit(EXIT_SUCCESS);
}
Upvotes: 1