Thread: Dynamic memory allocation with files.

  1. #1
    Registered User
    Join Date
    Feb 2012
    Posts
    117

    Dynamic memory allocation with files.

    On spring break now and my next assignment is going to be with Dynamic memory allocation so I figured I'd fool around with it to see how it works exactly.

    I understand the syntax of it.
    But for example if I had a file of a unknown number of lines and I wanted to allocate enough memory to store each of those lines in an array or structure of arrays, How would I do that?

    Say I had just a list of names..

    Bob
    Jerry
    Jeff
    Ken
    Lary
    Matt

    If I didn't want to hard code the number of names in this file, how would I allocate the memory of the amount of lines in the file?

    would this be a semi-correct format?
    I'm using this code as a reference, but we haven't learned realloc yet.

    Dynamic memory allocation - reading a file of unknown length - C example

    Code:
    int main(void){
        FILE *fp;
        char buffer[50];
        char *names;
        int counter = 0;
        
        if ( (fp = fopen("names.csv", "r" )) == NULL )
        {
        printf("Couldn't open file\n");
        exit(1); 
        }
    
    
        while(fgets(buffer, sizeof(buffer), fp))
        {
            names = malloc( counter * sizeof(char));  
            counter ++;         
        }
     getchar();
     return 0;
    }
    Last edited by mgracecar; 03-15-2012 at 04:32 PM.

  2. #2
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    No, that won't work. If you don't want to use realloc then you'll have to read the file twice. The first time you count the number of lines. Then you malloc that many char*'s for a char** array. Then read the file again and do something like what you're doing. In the code you've posted you've also used counter incorrectly (it doesn't represent the number of chars you want to malloc).
    Code:
    int main(void) {
        FILE *fp;
        char buffer[256];
        char **names, *p;
        int nlines = 0;
    
        /* TODO: read file and count lines */
    
        names = malloc(nlines * sizeof(char*));
        /* TODO: test that malloc succeeded */
    
        rewind(fp);
        nlines = 0;
        while (fgets(buffer, sizeof(buffer), fp)) {
            if ((p = strchr(buffer, '\n')) != NULL)
                *p = '\0'; /* remove newline character */
            names[nlines] = malloc(strlen(buffer) + 1);
            /* TODO: test that malloc succeeded */
            nlines++;
        }
        fclose(fp);
    
        /* TODO: do something with the lines */
    
        /* TODO: Free everything */
    
        return 0;
    }
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  3. #3
    Registered User
    Join Date
    Dec 2011
    Posts
    795
    You don't need to multiply by sizeof(char), it's ALWAYS 1. I think you mean sizeof(buffer).

    Also, the concept of "re-allocating" without freeing or using realloc() every time is prone to be leaky. Also, the first time, you're allocating nothing. Explanation:

    Code:
    First time through the loop:
    ...names = 0x342345234
    ...space allocated = 1 * 0 = 0
    ...*names = 0x0
    
    Second time through the loop:
    ...names = 0x23567546 /* a different location, idk */
    ...space allocated = 1 * 1 = 1
    ...*names = (whatever's in memory there)
    So, eventually, you'll run out of places for names to point to, and each one will be different. Not only are you losing any data you receive, you're not allocating enough space, and even worse, you're not freeing anything.

    Remember, a realloc() NEEDS to have three steps:
    > Allocate a newly sized block of memory
    > Copy old data into new data area
    > Free old memory block

  4. #4
    Registered User TheBigH's Avatar
    Join Date
    May 2010
    Location
    Melbourne, Australia
    Posts
    426
    If you don't want to read through the file twice, you could build a linked list of strings, sort of like this:

    Code:
    typedef struct string_list {
       char line[MAX_LINE_LENGTH];
       struct string_list *next;
    } String_list;
    This will allow you to allocate new memory for each line of the input file as it comes in.
    Code:
    while(!asleep) {
       sheep++;
    }

  5. #5
    Registered User
    Join Date
    Feb 2012
    Posts
    117
    Ok so basically realloc would be the easiest way to do that? Or the linked list of strings as TheBigH was saying. I can go look up how realloc works now. Only wanting to read through the file once. Thanks for the help!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Dynamic Memory Allocation
    By slash.hack in forum C Programming
    Replies: 9
    Last Post: 09-30-2011, 04:31 AM
  2. Dynamic Memory Allocation
    By JamesD in forum C Programming
    Replies: 10
    Last Post: 03-12-2011, 12:08 AM
  3. dynamic memory allocation
    By inquisitive in forum C++ Programming
    Replies: 5
    Last Post: 03-13-2004, 02:07 AM
  4. dynamic memory allocation - Please help
    By Space_Cowboy in forum C++ Programming
    Replies: 5
    Last Post: 11-13-2002, 05:20 PM
  5. Dynamic Memory Allocation
    By fr0ggs in forum C++ Programming
    Replies: 2
    Last Post: 10-26-2001, 03:34 AM