Thread: Dynamic string array inside a struct.

  1. #1
    Registered User
    Join Date
    Nov 2014
    Location
    Centurion, Gauteng, South Africa
    Posts
    28

    Dynamic string array inside a struct.

    Just a quick question ; I'm trying to write a structure which can hold a bunch of strings and grow as more are added.

    Usually when using an array of strings I'd implement it like this.
    Code:
    char **arr = malloc(25 * sizeof(char));
    for(size_t i = 0 ; i < 250 ; i++)
             arr[i] = malloc(250);
    Where 25 is the amount of elements and 250 is the size of the largest string I would want to store?

    Without checking the returns value of malloc , this is just to show my thought process. Am I correct when I say that arr is now a pointer to a memory space which represents 25 other char pointers?

    Thus arr[2] for example would be the third pointer in the array of pointers , which I could in turn malloc to make space for a string such as above?

    Copying a value to this string would then work as
    Code:
    strcpy(arr[2],"Hello world");

    Structure itself:
    Code:
    typedef struct string_table{
            char **data;
            size_t entries;
            size_t chunkSize;
            size_t stringSize;
    }STRINGTABLE,stringTable;

    Allocating memory for the structure and data.
    Code:
    STRINGTABLE *constructSt(size_t cs,size_t ss){
            STRINGTABLE *st = malloc(sizeof(STRINGTABLE));
            if(!st)
                    return NULL;
    
    
            st->chunkSize = cs;
            st->stringSize = ss;
            st->entries = 0;
    
    
            st->data = malloc(cs);
            if(!st->data)
                    return NULL;
    
    
            for(size_t i =0 ; i < cs ; i++){
                    (st->data[i]) = malloc(ss);
                    if(!(st->data[i]))
                            return NULL;
            }
    
    
            return st;
    }

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    No, it should be:
    Code:
    char **arr = malloc(25 * sizeof(*arr));
    for (size_t i = 0; i < 25; i++)
             arr[i] = malloc(250);
    Even then, the above is incomplete since it does not check the return value of malloc. But note the differences:
    • sizeof(*arr) instead of sizeof(char). You could use sizeof(char*) instead, but sizeof(*arr) can be verified as correct even without checking the type of arr (unless arr is a void*, but then the compiler will report an error).
    • Loop 25 times, not 250 times: you want 25 strings, not 250 strings.


    Quote Originally Posted by RagingGrim
    Allocating memory for the structure and data.
    Now you are checking the return value of malloc, which is good, but remember that before you return, you need to deallocate memory that was already allocated.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by RagingGrim View Post
    Am I correct when I say that arr is now a pointer to a memory space which represents 25 other char pointers?

    Thus arr[2] for example would be the third pointer in the array of pointers , which I could in turn malloc to make space for a string such as above?
    Yes, that is correct
    EDIT: Except for the errors that laserlight caught that I didn't. Fix those.

    Quote Originally Posted by RagingGrim View Post
    Copying a value to this string would then work as
    Code:
    strcpy(arr[2],"Hello world");
    Yes, though of course strcpy could run off the end of that array, and overflow; strncpy would be safer.

    You're definitely on the right track. Some notes on your implementation though:

    • Your struct members have slightly confusing names. A chunk to me sounds like one element of st->data, one chunk of memory the string occupies. chunkSize isn't really the chunk size then, it's max entries. stringSize isn't really string size, it's the size of one chunk (or element).
    • If you intend data to represent a single string, you're causing extra work by using multiple chunks. Figuring out when you exceed the chunk size for an entry, and need to wrap to the next one is not much work, but it's is error prone, especially for buffer overrun and off-by-one type errors. Instead, look into using realloc to grow the string.
    • Your malloc(cs) call is incorrect, you need to multiply by sizeof(*st->data)1.
    • If one of the later malloc's for data[i] fails, you need to free all the memory you allocated up to that point, otherwise you have a memory leak. Loop from i (or may i-1) back down to 0, calling free(st->data[i]). Then free(st->data). Then return NULL;
    • If you are going to pre-allocate all the elements in data[i], you might as well just use a single large array, as you're not saving any memory.

    1 Note that I used the pointer itself here: sizeof(*st->data) instead of sizeof(char *). In general, that idiom is preferred, it means less work if you ever change the type of st->data. Imagine you want this code to start supporting unicode characters at some point. No need to change the malloc call, and no need to worry about forgetting to change it.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Sorting array of struct inside struct
    By blueboyz in forum C Programming
    Replies: 13
    Last Post: 04-24-2012, 02:15 AM
  2. Replies: 10
    Last Post: 12-03-2011, 02:26 PM
  3. array inside struct
    By tat in forum C Programming
    Replies: 15
    Last Post: 11-13-2007, 12:36 PM
  4. How to access a dynamic array inside a std::set ?
    By IndioDoido in forum C++ Programming
    Replies: 16
    Last Post: 11-04-2007, 05:27 PM
  5. initializing char array inside a struct
    By panos in forum C Programming
    Replies: 6
    Last Post: 06-01-2007, 06:43 PM

Tags for this Thread