Dynamic Memory Allocation for Reading String

Discussion in 'C Programming' started by dough, Oct 4, 2005.

  1. dough

    dough Guest

    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.
     
    dough, Oct 4, 2005
    #1
    1. Advertising

  2. dough wrote:
    > 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.

    > foo(s) /* do something with s */
    > }
    > free(s);
    >
    > When complied, I get a segmentation error which means my allocation is
    > invalid somewhere.


    Obviously.

    > Please take a look and provide any comments.
    > Thanks.
    >
     
    Martin Ambuhl, Oct 4, 2005
    #2
    1. Advertising

  3. dough

    Suman Guest

    dough wrote:
    > 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!
     
    Suman, Oct 4, 2005
    #3
  4. "dough" <> writes:
    > 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.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Oct 4, 2005
    #4
  5. dough wrote:
    > 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.
     
    Chris Johnson, Oct 4, 2005
    #5
  6. "Chris Johnson" <> wrote in news:1128401860.308575.60000
    @g14g2000cwa.googlegroups.com:

    > 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

    --
    A. Sinan Unur <>
    (reverse each component and remove .invalid for email address)
     
    A. Sinan Unur, Oct 4, 2005
    #6
  7. dough

    Skarmander Guest

    Keith Thompson wrote:
    > "dough" <> writes:
    >
    >>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 */
    >>
    >> f = "somefile.txt";

    <snip>
    > 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.
     
    Skarmander, Oct 4, 2005
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. s.subbarayan

    Dynamic memory allocation and memory leak...

    s.subbarayan, Mar 18, 2005, in forum: C Programming
    Replies:
    10
    Views:
    709
    Eric Sosman
    Mar 22, 2005
  2. Henk
    Replies:
    4
    Views:
    853
  3. Ken
    Replies:
    24
    Views:
    3,879
    Ben Bacarisse
    Nov 30, 2006
  4. chris
    Replies:
    6
    Views:
    997
    chris
    Oct 28, 2005
  5. Replies:
    4
    Views:
    356
    Peter Nilsson
    May 7, 2008
Loading...

Share This Page