Thread: Dynamicly resize array of strings

  1. #1
    Registered User
    Join Date
    Oct 2010
    Posts
    4

    Question Dynamicly resize array of strings

    I've made a simple demo (see below) that calls a function which adds some strings to an array. What I don't understand is why if I comment the malloc statements in the addSomeStrings function, everything still works ok. Is this just by chance or are those statements not needed?

    I ask because I have something similar in an application I am developing which works fine without the malloc statements but with them it throws a segmentation fault when i try and display the strings in the array (output of strtok function).

    Any help would be most appreciated.

    Code:
        void addSomeStrings(char **data)
        {
            printf("Allocating heap space\n");
            data[0] = (char *) malloc(5*sizeof(char *));
            data[0] = "first";
            
            printf("Reallocating heap space\n");
            data = (char **) realloc(data, 2 * sizeof(char *));
            data[1] = (char *) malloc(6*sizeof(char *));
            data[1] = "second";
            
            printf("Reallocating heap space\n");
            data = (char **) realloc(data, 3 * sizeof(char *));
            data[2] = (char *) malloc(5*sizeof(char *));
            data[2] = "third";
            
        }
    
        int main()
        {
            char **data;
            int i=0;
            
            data = (char **)malloc(sizeof(char *));
            
            addSomeStrings(data);
                
            for (i=0; i<3; i++)
            {
                printf("String %s\n", data[i]);
            }
            
            return 0;
        }

  2. #2
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    You got it all wrong.

    Code:
         void addSomeStrings(char **data)
        {
            printf("Allocating heap space\n");
            data[0] = (char *) malloc(5*sizeof(char *));    
            data[0] = "first";                             // mem leak, use strcpy(data[0],"first");
            
            printf("Reallocating heap space\n");
            data = (char **) realloc(data, 2 * sizeof(char *));  // won't change in caller, leak again
            data[1] = (char *) malloc(6*sizeof(char *));
            data[1] = "second";
            
            printf("Reallocating heap space\n");
            data = (char **) realloc(data, 3 * sizeof(char *));
            data[2] = (char *) malloc(5*sizeof(char *));
            data[2] = "third";
            
        }
    
        int main()
        {
            char **data;
            int i=0;
            
            data = (char **)malloc(sizeof(char *)); // prefer T *p = malloc(sizeof(*p));
            
            addSomeStrings(data);
                
            for (i=0; i<3; i++)
            {
                printf("String %s\n", data[i]);
            }
            
            return 0;
        }
    I suggest you read a good tutorial on pointer,dynamic memory allocation...
    Last edited by Bayint Naung; 10-13-2010 at 02:40 AM.

  3. #3
    Registered User
    Join Date
    Oct 2010
    Posts
    4
    Thanks for the reply, I understand now about using strcpy, and I see now why realloc will not change the value in the caller - but I am not sure how to fix it. Should I change the function to accept char *** ?

  4. #4
    Registered User
    Join Date
    Oct 2010
    Posts
    4
    I've modified my code and set it to run in a loop so I can check if it eats memory, and it doesn't. I think it's correct now - any comments would be very welcome!

    Code:
        void addSomeStrings(char ***input)
        {
            char **data;
            
            data = (char **) realloc(*input, 1 * sizeof(char *));
            data[0] = (char *) malloc(6*sizeof(char *));
            strcpy(data[0], "first");
            
            data = (char **) realloc(data, 2 * sizeof(char *));
            data[1] = (char *) malloc(7*sizeof(char *));
            strcpy(data[1], "second");
            
            data = (char **) realloc(data, 3 * sizeof(char *));
            data[2] =  malloc(6*sizeof(char ));
            strcpy(data[2], "third");
    
        }
        
        int main()
        {
            char **data;
            
            while (1)
            {
                /* Allocate space for array */
                data = (char **)malloc(sizeof(char *));
                
                /* Add 3 strings */
                addSomeStrings(&data);
                
                /* Free pointers to each string */
                free(data[0]);
                free(data[1]);
                free(data[2]);
                
                /* Free initial pointer */
                free(data);
                
                usleep(10000);
            }
                
            
            return 0;
        }

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > data = (char **) realloc(*input, 1 * sizeof(char *));
    You also need
    *input = data;
    when you are done, because realloc may move the block of memory.

    You're basically being lucky at the moment because it can extend the current block without having to move it.

    > data[0] = (char *) malloc(6*sizeof(char *));
    1. Don't cast the result of malloc in a C program - see the FAQ. You're in danger of hiding a serious error.
    2. It should be sizeof(char), not sizeof(char*)


    > data = (char **)malloc(sizeof(char *));
    realloc is capable of starting from NULL. There is no need to have an initial malloc before calling realloc. In fact, you can do EVERYTHING with just realloc, including 'free'.
    So
    data = NULL;
    is an acceptable starting point.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Oct 2010
    Posts
    4
    Thanks - that worked a treat.

    You're basically being lucky at the moment
    I guessed something like this was going on as in my larger application it was segfaulting, now it works fine.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 16
    Last Post: 05-29-2009, 07:25 PM
  2. Replies: 2
    Last Post: 07-11-2008, 07:39 AM
  3. Build an array of strings dynamically
    By Nazgulled in forum C Programming
    Replies: 29
    Last Post: 04-07-2007, 09:35 PM
  4. question about multidimensional arrays
    By richdb in forum C Programming
    Replies: 22
    Last Post: 02-26-2006, 09:51 AM
  5. Array of strings in C
    By szill in forum C Programming
    Replies: 10
    Last Post: 02-22-2005, 05:03 PM

Tags for this Thread