Dynamic Memory Allocation for Reading String

D

dough

Heres a snippet of my code. I am trying to dynamically allocate memory
for reading in strings from a file.

FILE *f; /* file to read */
char *s; /* string being read */

f = "somefile.txt";
s = malloc(sizeof(char*)); /* allocates mem of string */
while( fscanf(f, "%s", s) != EOF )
{ /* read from FILE */
realloc(s, strlen(s)+1); /* reallocate that mem */
foo(s) /* do something with s */
}
free(s);

When complied, I get a segmentation error which means my allocation is
invalid somewhere. Please take a look and provide any comments.
Thanks.
 
M

Martin Ambuhl

dough said:
Heres a snippet of my code. I am trying to dynamically allocate memory
for reading in strings from a file.

FILE *f; /* file to read */
char *s; /* string being read */

f = "somefile.txt";
s = malloc(sizeof(char*)); /* allocates mem of string */

The line above makes no sense. There is no reason to suppose that an
area the size of a pointer to char is useful at all, especially when
while( fscanf(f, "%s", s) != EOF )
tries to cram a string of unknown length into such a tiny space.
The use of fscanf is unlikely to be a good idea here, even when
reasonable choices for the argument to malloc.
{ /* read from FILE */
realloc(s, strlen(s)+1); /* reallocate that mem */

The above line seems to be based on a fundamental contradiction. It
assumes that a string has been properly read via fscanf. Unless that
string is shorter than the space allocated for s -- very unlikely since
s was allocated a very tiny space to start with -- this reallocation
would imply that s is being given needed space for the string which it
already had space for.
 
S

Suman

dough said:
Heres a snippet of my code. I am trying to dynamically allocate memory
for reading in strings from a file.

FILE *f; /* file to read */
char *s; /* string being read */

f = "somefile.txt";
s = malloc(sizeof(char*)); /* allocates mem of string */

It doesn't do what you want it to do. It allocates space for an object
whose size equals `sizeof(char *)'. So, if sizeof(char *) on your
system is 4, you can store a string with a maximum of 3 characters
and no more.

Since you want to store a
string allocate enough room for the biggest string that you might
find in the file, add one for the terminating
'\0' and do something like:
#define MAXSTRSIZE 30
...
s = malloc( MAXSTRSIZE + 1 )
while( fscanf(f, "%s", s) != EOF )
{ /* read from FILE */
realloc(s, strlen(s)+1); /* reallocate that mem */

Why would you want this?

[ ...]
When complied, I get a segmentation error which means my allocation is
invalid somewhere.

Yes, that's possible, as there's probably not enough room for the
string
you read in, and a access-out-of-bounds happens. And BOOM!
 
K

Keith Thompson

dough said:
Heres a snippet of my code. I am trying to dynamically allocate memory
for reading in strings from a file.

FILE *f; /* file to read */
char *s; /* string being read */

f = "somefile.txt";
s = malloc(sizeof(char*)); /* allocates mem of string */
while( fscanf(f, "%s", s) != EOF )
{ /* read from FILE */
realloc(s, strlen(s)+1); /* reallocate that mem */
foo(s) /* do something with s */
}
free(s);

When complied, I get a segmentation error which means my allocation is
invalid somewhere. Please take a look and provide any comments.
Thanks.

Please post real compilable code.

The statement
f = "somefile.txt";
makes no sense; probably your real code uses fopen().

The statement
s = malloc(sizeof(char*));
allocates enough space for a pointer-to-char; it doesn't allocate
space for the string it pointes to.

The call
fscanf(f, "%s", s)
is unsafe. The "%s" format matches a sequence of non-whitespace
characters; it doesn't specify the maximum length, so there's no way
to guard against overflowing the allocated buffer. (Do you want to
read sequences of non-whitespace character, or entire lines?)

You don't capture the result of realloc(), but by the time you call it
it's probably too late; chances are you've already overflowed your
buffer.

Again, post your actual code, not a summary.
 
C

Chris Johnson

dough said:
Heres a snippet of my code. I am trying to dynamically allocate memory
for reading in strings from a file.

FILE *f; /* file to read */
char *s; /* string being read */

f = "somefile.txt";

f = fopen("somefile.txt","r");
s = malloc(sizeof(char*)); /* allocates mem of string */

You're getting the size of a pointer why? s is going to be a very short
string.
while( fscanf(f, "%s", s) != EOF )

I don't see why you fscanf to get a string. Why not use fgets()?
*scanf() is mostly useful for parsing out numbers, or complex
combinations, for instance:

sscanf(timestamp, "%d:%d:%d - %s",hour,minute,second,message)

or something like that.
{ /* read from FILE */
realloc(s, strlen(s)+1); /* reallocate that mem */

You're increasing s by one byte every time. Is each line one character
longer than the last?
foo(s) /* do something with s */
}
free(s);

When complied, I get a segmentation error which means my allocation is
invalid somewhere.

Actually, it can mean any number of things. It will either be with your
odd use of allocation or your string instead of FILE for input. (I'd
guess the latter.)
Please take a look and provide any comments.
Thanks.


I don't see why you're dynamically allocating in the first place.
You're only using one string, so there's no great need for malloc().

Pick a number that's at least a little bit larger (2 bytes, for the
\n\0 sequence) than the longest line you could possibly expect in your
file, and just use that. Unless you've got a function to predict how
many characters it's going to be, there's no way to allocate
intelligently without first having the string.
 
A

A. Sinan Unur

Pick a number that's at least a little bit larger (2 bytes, for the
\n\0 sequence) than the longest line you could possibly expect in your
file,

And, one day, the program will have to read a file that is slightly larger
than the largest size you expected.

Starting with a buffer of given size, reading chunks of input, and
realloc'ing as necessary would be a proper strategy for reading input of
unknown size.

Sinan
 
S

Skarmander

Please post real compilable code.

The statement
f = "somefile.txt";
makes no sense; probably your real code uses fopen().
<snip>

Compiles on my system. >:) Of course, the compiler is kind enough to
issue a warning...

S.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top