Thread: Duplicating contents of an array filled with pointers in C

  1. #1
    Registered User
    Join Date
    Mar 2014
    Posts
    7

    Duplicating contents of an array filled with pointers in C

    The following code is supposed to initialize a linked list of data, then generate all the possible combinations of the sub categories in the linked list. I then want to create a new linked list of data which contains the combinations (which point to the original data instead of copying the data itself).

    The only problem is I'm only able to point to the intermediary array that temporarily stores the pointers to the original data. How can I create pointers to the original data Then again there could always be something else in the mix of things that I'm missing

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    //////////////////////////////////////// Nested Structs / Linked lists ////////////////////////////////////////
    
    
    //////////////////// Parent/Child Nested Structure ////////////////////
    
    
    struct child
    {
        char name[15];
        int number;
        struct child *next;
    };
    
    
    struct parent
    {
        char *name;
        struct child *head_child;
        struct parent *next;
    };
    
    
    //////////////////// Combination List Structure ////////////////////
    
    
    struct list
    {
        char *parent_name;
        struct child *chosen_child;
    };
    
    
    struct list_collection
    {
        struct list_collection *next;
        struct list *current;           // will be an array
    };
    
    
    ////////// Global Variables //////////
    
    
    struct child *current_child;
    
    
    struct parent *head_parent;
    struct parent *current_parent;
    
    
    struct list_collection *head_list;
    struct list_collection *current_list;
    
    
    //////////////////////////////////////// Functions ////////////////////////////////////////
    
    
    ///////////////////////// Display Function /////////////////////////
    
    
    void display_list()
    {
        struct list_collection *temp;
        struct list_collection *previous;
        int c;
        
        current_list = head_list;
        temp = current_list;
        
        printf("\n********************************************************\n");
        while(current_list != NULL)
        {
            printf("\n----------------------------------------\n\n");
            
            for(c = 0; c < 2; c++)
            {
                printf("Parent Name: %s\n", temp->current[c].parent_name);
                printf("Child Name:     %s\n", temp->current[c].chosen_child->name);
                printf("Child Number:     %d\n", temp->current[c].chosen_child->number);
            }
            previous = current_list;
            current_list = current_list->next;
        }
        current_list = previous;
    }
    
    
    ///////////////////////// Add Functions /////////////////////////
    
    
    void add_parent(char *name, size_t size)
    {
        struct parent *temp;
        temp = malloc(sizeof(struct parent));
        temp->name = malloc(size);
        strcpy(temp->name, name);
        
        if (head_parent == NULL)
        {
            head_parent = temp;
            head_parent->next = NULL;
            head_parent->head_child = NULL;
            current_parent = head_parent;
        }
        
        else
        {
            current_parent->next = temp;
            current_parent->next->next = NULL;
            current_parent->next->head_child = NULL;
            current_parent = current_parent->next;
        }
    }
    
    
    void add_child(char name[15], int num)
    {
        struct child *temp;
        temp = malloc(sizeof(struct child));
        strcpy(temp->name, name);
        temp->number = num;
        
        if (current_parent->head_child == NULL)
        {
            current_parent->head_child = temp;
            current_parent->head_child->next = NULL;
            current_child = current_parent->head_child;
        }
        
        else
        {
            current_child->next = temp;
            current_child = current_child->next;
            current_child->next = NULL;
        }
    }
    
    
    void add_list(struct list *new_combination)
    {
        struct list_collection *temp;
        temp = malloc(sizeof(struct list_collection));
        temp->current = new_combination;
        
        //*temp->current = *new_combination;
        
        //memcpy(temp->current, new_combination, sizeof(struct list));
        
        /*for(c = 0; c < 2; c++)
        {
            temp->current[c] = new_combination[c];
            temp->current[c].parent_name = new_combination[c].parent_name;
            temp->current[c].chosen_child = new_combination[c].chosen_child;
            temp->current[c].chosen_child->number = new_combination[c].chosen_child->number;
        }*/
        
        if (head_list == NULL)
        {
            head_list = temp;
            head_list->next = NULL;
            current_list = head_list;
        }
        
        else
        {
            current_list->next = temp;
            current_list->next->next = NULL;
            current_list = current_list->next;
        }
    }
    
    
    void generate_list()
    {
        
        int c = 0;
        struct list temp[2];
        struct parent *parent_t;
        struct child *head[2];
        
        // initialize the first list
        
        parent_t = head_parent;
        
        while(parent_t != NULL)
        {
            temp[c].parent_name = parent_t->name;
            temp[c].chosen_child = parent_t->head_child;
            *head[c] = *parent_t->head_child;
            c++;
            parent_t = parent_t->next;
        }
        
        ////////// Genreate all possible parent/child combinations //////////
        
        c = 0;
        
        //////////////////// BELOW IS WHERE THE PROBLEM RESIDES ////////////////////
        
        /* 
           Problem: each time a new list is added, since each list points to "temp" instead of a
           direct pointer to the original data, each time temp changes here, all the data in list
           changes to what "temp" is.
        */
        
        while(temp[c].chosen_child != NULL)
        {
            while(temp[c+1].chosen_child != NULL)
            {
                add_list(temp);
                temp[c+1].chosen_child = temp[c+1].chosen_child->next;
            }
            temp[c].chosen_child = temp[c].chosen_child->next;
            temp[c+1].chosen_child = head[c+1];
        }
        
        //////////////////// END OF PROBLEM ////////////////////
    }
    
    
    void initialize()
    {
        char other_name[15], *name;
        int num;
        head_parent = NULL;
        head_list = NULL;
        name = malloc(4);
        
        //////////////////// Initialization of dynamic structures with data ////////////////////
        
        ////////// First parent & child dynamic structure //////////
        
        // Parent
        strcpy(name, "one\0");
        add_parent(name, strlen(name) + 1);
        
        // Child
        strcpy(other_name, "first\0");
        num = 1;
        add_child(other_name, num);
        
        strcpy(other_name, "second\0");
        num = 2;
        add_child(other_name, num);
        
        ////////// Second parent & child dynamic structure //////////
        
        // Parent
        strcpy(name, "two\0");
        add_parent(name, strlen(name) + 1);
        
        // Child
        strcpy(other_name, "first\0");
        num = 1;
        add_child(other_name, num);
        
        strcpy(other_name, "second\0");
        num = 2;
        add_child(other_name, num);
        
        strcpy(other_name, "third\0");
        num = 3;
        add_child(other_name, num);
    }
    
    
    //////////////////////////////////////// M A I N   R O U T I N E ////////////////////////////////////////
    
    
    int  main()
    {
        initialize();
        generate_list();
        display_list();
        
        return 0;
    }
    I believe the problem resides at Line 129 where I try to copy the array of pointers to original data, but it may start in the generate() routine starting at Line 158. I commented out in the add_list() routine other methods I tried without success (Line 131, Line 133, Line 135). Normally solve coding problems within day but this has taken me almost a week now plz excuse my noobyness, and thank you in advance

  2. #2
    Registered User
    Join Date
    Jun 2017
    Posts
    88
    You certainly have some interesting code. It is difficult for me to keep track of where all your pointers are going, and the way you use your structs is different from the way I am used to doing myself. Anyway, I am looking at line 183:
    Code:
    struct child *head[2];
    
    // initialize the first list
    
    parent_t = head_parent;
    
    while)parent_t != NULL)
    {
         temp[c].parent_name = parent_t->name;
         temp[c].chosen_child = parent_t->head_child;
         *head[c] = *parent_t->head_child;
    It is the last line that gives a writing access violation. Is *head[c] correct? What are you trying to dereference on the right side?

  3. #3
    Registered User
    Join Date
    Mar 2014
    Posts
    7
    oops good catch, yes that should read

    Code:
    head[c] = parent_t->head_child;
    Still there's the problem in Line 129 trying to copy pointers to the original data, instead of pointing to the intermediary pointer that iterates through the data. If you place
    Code:
    display();
    at the end of the
    Code:
    void add_list(struct list *new_combination)
    {
    }

    routine you can see exactly what happens
    Last edited by snorklebort; 11-25-2017 at 07:12 AM.

  4. #4
    Registered User
    Join Date
    Jun 2017
    Posts
    88
    I realized one second later I was wrong in what I said in this post.

  5. #5
    Registered User
    Join Date
    Jun 2017
    Posts
    88
    Code:
    void display_list()
    {
        struct list_collection *temp;
        struct list_collection *previous;
        int c;
    
        current_list = head_list;
        temp = current_list;
    
        printf("\n********************************************************\n");
        while (current_list != NULL)
        {
            printf("\n----------------------------------------\n\n");
    
            for (c = 0; c < 2; c++)
            {
                printf("Parent Name: %s\n", temp->current[c].parent_name);
                printf("Child Name:     %s\n", temp->current[c].chosen_child->name);
                printf("Child Number:     %d\n", temp->current[c].chosen_child->number);
            }
            previous = current_list;
            current_list = current_list->next;
        }
        current_list = previous;
    }
    I think on line 82 head_list->current[0] doesn't have initialized data. All of its members have no data, so when you try to read it, you get a read access violation.

  6. #6
    Registered User
    Join Date
    Mar 2014
    Posts
    7
    That is correct, in the display_list() routine, head_list[0].chosen_child isn't initialized, and here's why that's happening:

    In the generate_list() routine, this part:

    Code:
    while(temp[c].chosen_child != NULL)
    {
            while(temp[c+1].chosen_child != NULL)
            {
                add_list(temp);
                temp[c+1].chosen_child = temp[c+1].chosen_child->next;
            }
            temp[c].chosen_child = temp[c].chosen_child->next;
            temp[c+1].chosen_child = head[c+1];
    }
    when the loop is at it's last run,

    temp[c+1].chosen_child = temp[c+1].chosen_child->next;

    and

    temp[c].chosen_child = temp[c].chosen_child->next;

    increment to the next item in the linked list (which is NULL), then the while loop reads false (== 0) so it exits, that's why there's a problem accessing that block of memory. The reason being that when I add a new item in the add_list() routine, it just creates a pointer to temp[c] instead of a pointer to the original data that temp[c] points to. So as temp[c] changes all the data in the new linked list changes.

  7. #7
    Registered User
    Join Date
    Mar 2014
    Posts
    7
    If I place display_list(); right after add_list(temp); in the loop I mentioned above earlier ( Line 194 ), this is the resulting output:

    ( showing that it successfully creates the list of combinations and appends new items to the linked list, however all the data (including data already added to the list) all points to the same value which temp[c] currently is ). Each time a new item is added it is separated with *********, and each node is separated with ------------

    Code:
    ********************************************************
    
    
    ----------------------------------------
    
    
    Parent Name: one
    Child Name:     first
    Child Number:     1
    Parent Name: two
    Child Name:     first
    Child Number:     1
    
    
    ********************************************************
    
    
    ----------------------------------------
    
    
    Parent Name: one
    Child Name:     first
    Child Number:     1
    Parent Name: two
    Child Name:     second
    Child Number:     2
    
    
    ----------------------------------------
    
    
    Parent Name: one
    Child Name:     first
    Child Number:     1
    Parent Name: two
    Child Name:     second
    Child Number:     2
    
    
    ********************************************************
    
    
    ----------------------------------------
    
    
    Parent Name: one
    Child Name:     first
    Child Number:     1
    Parent Name: two
    Child Name:     third
    Child Number:     3
    
    
    ----------------------------------------
    
    
    Parent Name: one
    Child Name:     first
    Child Number:     1
    Parent Name: two
    Child Name:     third
    Child Number:     3
    
    
    ----------------------------------------
    
    
    Parent Name: one
    Child Name:     first
    Child Number:     1
    Parent Name: two
    Child Name:     third
    Child Number:     3
    
    
    ********************************************************
    
    
    ----------------------------------------
    
    
    Parent Name: one
    Child Name:     second
    Child Number:     2
    Parent Name: two
    Child Name:     first
    Child Number:     1
    
    
    ----------------------------------------
    
    
    Parent Name: one
    Child Name:     second
    Child Number:     2
    Parent Name: two
    Child Name:     first
    Child Number:     1
    
    
    ----------------------------------------
    
    
    Parent Name: one
    Child Name:     second
    Child Number:     2
    Parent Name: two
    Child Name:     first
    Child Number:     1
    
    
    ----------------------------------------
    
    
    Parent Name: one
    Child Name:     second
    Child Number:     2
    Parent Name: two
    Child Name:     first
    Child Number:     1
    
    
    ********************************************************
    
    
    ----------------------------------------
    
    
    Parent Name: one
    Child Name:     second
    Child Number:     2
    Parent Name: two
    Child Name:     second
    Child Number:     2
    
    
    ----------------------------------------
    
    
    Parent Name: one
    Child Name:     second
    Child Number:     2
    Parent Name: two
    Child Name:     second
    Child Number:     2
    
    
    ----------------------------------------
    
    
    Parent Name: one
    Child Name:     second
    Child Number:     2
    Parent Name: two
    Child Name:     second
    Child Number:     2
    
    
    ----------------------------------------
    
    
    Parent Name: one
    Child Name:     second
    Child Number:     2
    Parent Name: two
    Child Name:     second
    Child Number:     2
    
    
    ----------------------------------------
    
    
    Parent Name: one
    Child Name:     second
    Child Number:     2
    Parent Name: two
    Child Name:     second
    Child Number:     2
    
    
    ********************************************************
    
    
    ----------------------------------------
    
    
    Parent Name: one
    Child Name:     second
    Child Number:     2
    Parent Name: two
    Child Name:     third
    Child Number:     3
    
    
    ----------------------------------------
    
    
    Parent Name: one
    Child Name:     second
    Child Number:     2
    Parent Name: two
    Child Name:     third
    Child Number:     3
    
    
    ----------------------------------------
    
    
    Parent Name: one
    Child Name:     second
    Child Number:     2
    Parent Name: two
    Child Name:     third
    Child Number:     3
    
    
    ----------------------------------------
    
    
    Parent Name: one
    Child Name:     second
    Child Number:     2
    Parent Name: two
    Child Name:     third
    Child Number:     3
    
    
    ----------------------------------------
    
    
    Parent Name: one
    Child Name:     second
    Child Number:     2
    Parent Name: two
    Child Name:     third
    Child Number:     3
    
    
    ----------------------------------------
    
    
    Parent Name: one
    Child Name:     second
    Child Number:     2
    Parent Name: two
    Child Name:     third
    Child Number:     3
    Last edited by snorklebort; 11-25-2017 at 02:40 PM.

  8. #8
    Registered User
    Join Date
    Mar 2014
    Posts
    7

    Problem solved!!!!!

    So it turns out I was allocating the encompassing linked list on the heap, but the sub contents of that linked list on the stack. Full code below, look at the beginning of the add_list() routine:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    //////////////////////////////////////// Nested Structs / Linked lists ////////////////////////////////////////
    
    
    //////////////////// Parent/Child Nested Structure ////////////////////
    
    
    struct child
    {
        char name[15];
        int number;
        struct child *next;
    };
    
    
    struct parent
    {
        char *name;
        struct child *head_child;
        struct parent *next;
    };
    
    
    //////////////////// Combination List Structure ////////////////////
    
    
    struct list
    {
        char *parent_name;
        struct child *chosen_child;
    };
    
    
    struct list_collection
    {
        struct list_collection *next;
        struct list *current;           // will be an array
    };
    
    
    ////////// Global Variables //////////
    
    
    struct child *current_child;
    
    
    struct parent *head_parent;
    struct parent *current_parent;
    
    
    struct list_collection *head_list;
    struct list_collection *current_list;
    
    
    //////////////////////////////////////// Functions ////////////////////////////////////////
    
    
    ///////////////////////// Display Function /////////////////////////
    
    
    void display_list()
    {
        struct list_collection *previous;
        int c;
        
        current_list = head_list;
        
        printf("\n********************************************************\n");
        while(current_list != NULL)
        {
            printf("\n----------------------------------------\n\n");
            
            for(c = 0; c < 2; c++)
            {
                printf("Parent Name: %s\n", current_list->current[c].parent_name);
                printf("Child Name:     %s\n", current_list->current[c].chosen_child->name);
                printf("Child Number:     %d\n", current_list->current[c].chosen_child->number);
            }
            previous = current_list;
            current_list = current_list->next;
        }
        current_list = previous;
    }
    
    
    ///////////////////////// Add Functions /////////////////////////
    
    
    void add_parent(char *name, size_t size)
    {
        struct parent *temp;
        temp = malloc(sizeof(struct parent));
        temp->name = malloc(size);
        strcpy(temp->name, name);
        
        if (head_parent == NULL)
        {
            head_parent = temp;
            head_parent->next = NULL;
            head_parent->head_child = NULL;
            current_parent = head_parent;
        }
        
        else
        {
            current_parent->next = temp;
            current_parent->next->next = NULL;
            current_parent->next->head_child = NULL;
            current_parent = current_parent->next;
        }
    }
    
    
    void add_child(char name[15], int num)
    {
        struct child *temp;
        temp = malloc(sizeof(struct child));
        strcpy(temp->name, name);
        temp->number = num;
        
        if (current_parent->head_child == NULL)
        {
            current_parent->head_child = temp;
            current_parent->head_child->next = NULL;
            current_child = current_parent->head_child;
        }
        
        else
        {
            current_child->next = temp;
            current_child = current_child->next;
            current_child->next = NULL;
        }
    }
    
    
    void add_list(struct list *new_combination)
    {
        int c;
        struct list_collection *temp = malloc(sizeof(struct list_collection));
        temp->current = malloc(sizeof(struct list) * 2);
        
        for(c = 0; c < 2; c++)
        {
            temp->current[c] = new_combination[c];
        }
        
        if (head_list == NULL)
        {
            head_list = temp;
            head_list->next = NULL;
            current_list = head_list;
        }
        
        else
        {
            current_list->next = temp;
            current_list = current_list->next;
            current_list->next = NULL;
        }
    }
    
    
    void generate_list()
    {
        int c = 0;
        struct list temp[2];
        struct parent *parent_t;
        struct child *head[2];
        
        // initialize the first list
        
        parent_t = head_parent;
        
        while(parent_t != NULL)
        {
            temp[c].parent_name = parent_t->name;
            temp[c].chosen_child = parent_t->head_child;
            head[c] = parent_t->head_child;
            c++;
            parent_t = parent_t->next;
        }
        
        ////////// Genreate all possible parent/child combinations //////////
        
        c = 0;
        
        while(temp[c].chosen_child != NULL)
        {
            while(temp[c+1].chosen_child != NULL)
            {
                add_list(temp);
                temp[c+1].chosen_child = temp[c+1].chosen_child->next;
            }
            temp[c].chosen_child = temp[c].chosen_child->next;
            temp[c+1].chosen_child = head[c+1];
        }
    }
    
    
    void initialize()
    {
        char other_name[15], *name;
        int num;
        head_parent = NULL;
        head_list = NULL;
        name = malloc(4);
        
        //////////////////// Initialization of dynamic structures with data ////////////////////
        
        ////////// First parent & child dynamic structure //////////
        
        // Parent
        strcpy(name, "one\0");
        add_parent(name, strlen(name) + 1);
        
        // Child
        strcpy(other_name, "first\0");
        num = 1;
        add_child(other_name, num);
        
        strcpy(other_name, "second\0");
        num = 2;
        add_child(other_name, num);
        
        ////////// Second parent & child dynamic structure //////////
        
        // Parent
        strcpy(name, "two\0");
        add_parent(name, strlen(name) + 1);
        
        // Child
        strcpy(other_name, "first\0");
        num = 1;
        add_child(other_name, num);
        
        strcpy(other_name, "second\0");
        num = 2;
        add_child(other_name, num);
        
        strcpy(other_name, "third\0");
        num = 3;
        add_child(other_name, num);
    }
    
    
    //////////////////////////////////////// M A I N   R O U T I N E ////////////////////////////////////////
    
    
    int  main()
    {
        initialize();
        generate_list();
        display_list();
        
        return 0;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to duplicating the Array & copy tokenPtr to an array
    By Watervase Chew in forum C Programming
    Replies: 21
    Last Post: 04-22-2013, 08:35 AM
  2. Checking to see if an array is filled
    By ljgerr93 in forum C Programming
    Replies: 5
    Last Post: 10-17-2011, 12:48 PM
  3. "duplicating" an array of pointers
    By budala in forum C Programming
    Replies: 6
    Last Post: 08-13-2009, 08:16 AM
  4. Duplicating specific binary data in array
    By chris.lloyd in forum C Programming
    Replies: 1
    Last Post: 10-21-2006, 09:54 PM
  5. Filled array
    By GaPe in forum C Programming
    Replies: 2
    Last Post: 12-11-2001, 05:36 AM

Tags for this Thread