Thread: Array of pointers to structs

  1. #1
    Registered User
    Join Date
    Sep 2016
    Posts
    41

    Array of pointers to structs

    Hey there guys,

    I am having a little trouble with implementing an aspect of searching an address book, in a little make-a-phone project, I'm working on.

    Basically I am trying to search through a known linked list, based on user input. Save the addresses of the nodes, containing matching names, to an array of pointers and then pass that array to a display function that simply iterates through said array and prints out the struct members.

    For example, If I have a list of contacts:

    David
    Darren
    Dominic
    Dominique
    Duran
    Dulan

    If I input 'D', then it will incidentally return the whole list, after saving the addresses of each of these nodes to an array of pointers. If I input 'Da', it will (again) save only the required node addresses to the array and then only print out 'David' and 'Darren'. The same goes for 'Do' with 'Dominic' and 'Dominique'. I think you get my point.

    However, I seem to be struggling with dereferencing pointers or the pointer used in the for loop of the disp_list_by_search() function. The following code runs smoothly up until the disp_list_by_search() function, at which point it segfaults for obvious reasons. I feel as though I am inadvertently pointing to the actual struct, which then increments the pointer there rather than incrementing the address of the array. (which ideally, would then move to the next index in the array and print out the members of that struct)

    I am no stranger to the basics of pointers and addressing, however my brain is starting to really hurt with this one.

    Here is the full code, runs smoothly up until I try to display based on input (a previous version was working quite well with a simple strcmp of the entire member and input, but I wanted to extend functionality to output based on a 'live' input search field i.e. if search_field > 0 disp_list_by_search(). This is my initial testing of that functionality):

    NOTE: THE OFFENDING FUNCTION IS AT THE BOTTOM, I think the pointer used in the for loop is where I am going wrong.

    Thanks in advance!!
    MedicineMan25

    Code:
    /*
     * To change this license header, choose License Headers in Project Properties.
     * To change this template file, choose Tools | Templates
     * and open the template in the editor.
     */
    
    
    /* 
     * File:   main.c
     * Author: access
     *
     * Created on September 4, 2017, 2:04 AM
     */
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdbool.h>
    
    
    
    
    int char_value;
    int int_convert_member;
    int int_convert_parameter;
    
    
    long input_convert;
    char user_input_c [3];
    char contact_name[24];
    
    
    const int contact_num_len = 24;
    const int contact_name_len = 24;
    
    
    void* sort_ptr = NULL;
    void* find_ptr = NULL;
    
    
    struct GSM_contact_s {
    
    
        struct GSM_contact_s *next;
        int contact_num[24];
        char contact_name[24];
    
    
    };
    
    
    /*
     * A pointer stack for traversal, addition and location 
     */
    
    
    struct GSM_contact_s *contact_head = NULL;
    struct GSM_contact_s *contact_tmp = NULL;
    struct GSM_contact_s *contact_ptr = NULL;
    struct GSM_contact_s *contact_prev = NULL;
    struct GSM_contact_s *contact_new = NULL;
    
    
    //struct GSM_contact_s *contact_find = NULL;
    struct GSM_contact_s *search_arr[256];
    
    
    struct GSM_contact_s *contact_travers_abc(char* contact_name, int index1);
    void *contact_travers_find(const char* contact_name);
    
    
    void contact_search(const char* contact_name);
    void contact_delete(const char* contact_name);
    void list_disp(struct GSM_contact_s *ptr);
    void list_disp_by_search(struct GSM_contact_s *ptr);
    
    
    void contact_create();
    void clear_name();
    void clear_input();
    
    
    
    
    /*
     * 
     */
    
    
    
    
    int main(int argc, char** argv) {
    
    
        
        
        do {
            
            printf("\n\nWelcome to your address book!! :) \n\n\n");
            printf("What would you like to do? \n\n");
            printf("1. Add a contact\n");
            printf("2. Search for a contact\n");
            printf("3. Delete a contact\n");
            printf("4. Display all contacts\n");
            printf("5. Exit\n\n");
            
            printf("Enter your choice:- ");
    
    
            fgets(user_input_c,sizeof(user_input_c),stdin);
            input_convert = strtol(&user_input_c[0], NULL, 10);
            
            printf("user_input_c = %d\n", user_input_c[0]);
            printf("input_convert = %ld\n\n", input_convert);
            
            switch(input_convert){
                case(1):
                    clear_name();
                    printf("\n\nYou have chosen to add a new contact. \n\nPlease enter a name...\n");
                    fgets(contact_name,sizeof(contact_name),stdin);
                    printf("You have entered %s\n\n", contact_name);
                    contact_create(contact_name, 0);
                    break;
                case(2):
                    clear_name();
                    printf("\n\nYou have chosen to find a contact. \n\nPlease enter a name...\n");
                    fgets(contact_name,sizeof(contact_name),stdin);
                    printf("\nLooking up name\n");
                    contact_search(contact_name);
                    break;
                case(3):
                    clear_name();
                    printf("\n\nYou have chosen to delete a contact. \n\nPlease enter a name...\n");
                    fgets(contact_name,sizeof(contact_name),stdin);
                    printf("\nLooking up name\n");
                    contact_delete(contact_name);
                case(4):
                    clear_name();
                    list_disp(contact_head);
                    break;
                case(5):
                    exit(1);
                    break;
                default:
                    clear_name();
                    printf("\n\nWrong entry, try again!!!"); 
            }
        } while (input_convert != 5);
        
        return (EXIT_SUCCESS);
    }
    
    
    
    
    void clear_name(){
        
        for(int i = 0; i < 24; i++){
            contact_name[i] = '\0';
        }
        
    }
    
    
    void contact_delete(const char* contact_name){
        
        contact_ptr = contact_travers_find(contact_name);
        
        if(contact_ptr == NULL){
            printf("The contact you were looking for could not be located");
        } else {
            printf("The contact you searched for has been found\n");
            printf("The contact is: %s\n", contact_ptr->contact_name);
            printf("Located at address %p\n\n", contact_ptr);
            contact_prev->next = contact_ptr->next;
            contact_ptr = NULL;
            printf("The contact has now been deleted\n Have a nice day!! :) \n");
        }
        contact_tmp = NULL;
        contact_prev = NULL;
        
    }
    
    
    void contact_search(const char* contact_name){
        
        contact_ptr = contact_travers_find(contact_name); 
        
        if(contact_ptr == NULL){
            printf("The contact you were looking for could not be located");
        } else {
            
            list_disp_by_search(contact_ptr); //
         
        }
        contact_tmp = NULL;
        contact_prev = NULL;
    }
    
    
    
    
    void *contact_travers_find(const char* contact_name){
    
    
        int name_length = strlen(contact_name);
        printf("name length = %d\n", name_length);
        
        for(int i = 0; i < 255; i++){
            search_arr[i] = NULL;
        }
        
        if (contact_tmp == NULL){    
            contact_tmp = contact_head;
        }
        
        bool name = false;
        
            if(contact_tmp != NULL){
                
                int i = 0;
                
                while(contact_tmp){ 
                    
                    name = (strncmp(contact_name, contact_tmp->contact_name, name_length -1) == 0);
                    
                    //printf("TEST %d\n", i++);
                    
                    if(!name){
                        printf("!name\n");
                        if(contact_tmp->next != NULL){
                            contact_tmp = contact_tmp->next;
                        } else {
                            printf("return search_arr[0] = %p \n", search_arr[0]);
                            return &search_arr[0]; //<----VRETURNING ADDRESS OF ARRAY MEMBER
                        }
                    } else if (name) {
                        printf("name\n");
                        search_arr[i] = contact_tmp;
                        printf("i = %d search_arr[i] = %p \n", i, search_arr[i]);
                        printf("contact_tmp = %p \n", contact_tmp);
                        i = ++i;
                        if(contact_tmp->next != NULL){
                            contact_tmp = contact_tmp->next;
                        } else {
                            printf("return search_arr[0] = %p \n", search_arr[0]);
                                return &search_arr[0]; // <---- RETURNING ADDRESS OF ARRAY MEMBER
                            }
                        }
                    } 
                
                }
            
    }
    
    
    
    
    void contact_create(char* contact_name){
        
        contact_ptr = contact_travers_abc(contact_name, 0);
    
    
        if(contact_ptr != NULL){
            strncpy(contact_ptr->contact_name, contact_name, contact_name_len);
            printf("\nNew node created at address: %p \nContact name: %s \n", contact_ptr, contact_ptr->contact_name);
        } else {
            printf("Error, memory was not allocated\n\n\n");
        }
        contact_ptr = NULL;
        printf ("contact_ptr = NULL \n");
    }
    
    
    
    
    struct GSM_contact_s *contact_travers_abc(char* contact_name, int index1){
    
    
        if(contact_head == NULL){
            
            contact_head = malloc(sizeof(struct GSM_contact_s));
            
            if(contact_head == NULL){
                printf("\nMemory Error: Initial head not allocated\n\n");
                return NULL;
            }
            
            contact_head->next = NULL;
            for(int i = 0; i < 24; i++){
                contact_head->contact_name[i] = '\0';
                contact_head->contact_num[i] = 0;
            }
            contact_tmp = (contact_head != NULL) ? contact_head : NULL;
            
            if(contact_tmp == NULL){
                printf ("\nMemory Error: Initial head not allocated\n\n");
                return NULL;
            }
            return contact_tmp;
            
        } else if (contact_tmp == NULL){
            contact_tmp = contact_head;
        }
    
    
        
        while(contact_tmp){
    
    
            printf("line 130: contact_tmp != NULL\n");
            int_convert_member = contact_tmp->contact_name[index1] < 96 ? contact_tmp->contact_name[index1] + 32 : contact_tmp->contact_name[index1];
            int_convert_parameter = contact_name[index1] < 96 ? contact_name[index1] + 32 : contact_name[index1];                     
            
            printf("\nint_convert_member = %d", int_convert_member);
            printf("\nint_convert_parameter = %d\n", int_convert_parameter);
     
        if(int_convert_parameter == int_convert_member){
    
    
                if ((contact_tmp->contact_name[index1] == '\0') && (contact_name[index1] == '\0')){
                    if(index1 > 0) { 
                        printf("\n\nContact name already exists!!! \n\n");
                        return NULL;
                    }  
                }
                    printf("line 140: int_conver_parameter == int_convert_member\n");
                sort_ptr = contact_travers_abc(contact_name, ++index1);
        
        } else if (int_convert_parameter < int_convert_member) {
                     
                printf("line 145: int_conver_parameter < int_convert_member\n");
                
                if(contact_prev != NULL){
                    
                    contact_new = malloc(sizeof(struct GSM_contact_s));
                    
                    if(contact_new == NULL){
                        printf("new contact memory not allocated");
                        return NULL;
                    }
                    
                    for(int i = 0; i < contact_name_len; i++){
                        contact_new->contact_name[i] = '\0';
                        contact_new->contact_num[i] = 0;
                    }
                    
                    contact_new->next = contact_prev->next;
                    contact_prev->next = contact_new;
                    
                    contact_prev = NULL;
                    contact_tmp = NULL;
                    
                    return contact_new;
                    
                } else {
                    
                    printf("line 152: contact_prev = NULL\n");
                    
                    contact_new = malloc(sizeof(struct GSM_contact_s));
                    
                    if(contact_new == NULL){
                        printf("new contact memory not allocated");
                        return NULL;
                    }
                    
                    for(int i = 0; i < contact_name_len; i++){
                        contact_new->contact_name[i] = '\0';
                        contact_new->contact_num[i] = 0;
                    }
                    
                    contact_new->next = contact_head;
                    contact_head = contact_new;
                    
                    contact_prev = NULL;
                    contact_tmp = NULL;
                    
                    return contact_new;
                    
                }
                    
            } else if ((int_convert_parameter != int_convert_member) && (int_convert_parameter > int_convert_member)) {
                
                //if the contact is alphabetically next or later in the list, move on to the next node
                contact_prev = contact_tmp;
                
                printf("int_convert_parameter != int_convert_member\n");
                
                //if you get to the end of the list, just add another node
                if(contact_tmp->next == NULL){
                    printf("contact_tmp->next == NULL\n");
                    contact_new = malloc(sizeof(struct GSM_contact_s));
                    
                    if(contact_new == NULL){
                        printf("new contact memory not allocated");
                        return NULL;
                    }
                    
                    for(int i = 0; i < contact_name_len; i++){
                        contact_new->contact_name[i] = '\0';
                        contact_new->contact_num[i] = 0;
                    }
                    
                    contact_tmp->next = contact_new;          
                    contact_new->next = NULL;
                    contact_prev = NULL;
                    contact_tmp = NULL;
                    
                    return contact_new;
                } else {
                    
                printf("line 174: contact_tmp != NULL\n");
                contact_tmp = contact_tmp->next;
                sort_ptr = contact_travers_abc(contact_name, 0);
                }
                
                
        }
                
        } //end while
    
    
        contact_tmp = NULL;
        contact_prev = NULL;
    
    
        return sort_ptr;
    }
    
    
    
    
    void list_disp(struct GSM_contact_s *ptr){
        
        contact_tmp = ptr;
        
        while(contact_tmp != NULL){
            
            printf("Name: %s", contact_tmp->contact_name);
            
            contact_tmp = contact_tmp->next ? contact_tmp->next : NULL;
            
        }
    } 
    
    //THE BELOW FUNCTION IS WHERE I AM STUMPED
    
    
    void list_disp_by_search(struct GSM_contact_s *ptr){
    
    
        for(ptr; ptr != NULL; ptr++){ //<----- CLEARLY THIS IS WRONG
                printf(ptr->contact_name); 
        }
    
    
    }

  2. #2
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,729
    Yeah, it seems wrong. What you probably need is:
    Code:
    for(; ptr != NULL; ptr = ptr->next){
    Devoted my life to programming...

  3. #3
    Registered User
    Join Date
    Sep 2016
    Posts
    41
    Can't edit so I'll just leave my solution here:

    I can't work out how to pass the address properly through to the display function, so I will just use the return as a NULL check. It will be as follows:

    Code:
    
    void list_disp_by_search(){
    
    
        for(int i = 0; search_arr[i] != NULL; i++){ <---- simplified
                printf(search_arr[i]->contact_name); <---incrementing index of array and access member of struct, which the pointer at desired index points to... 
        }
    
    
    }

  4. #4
    Banned
    Join Date
    Aug 2017
    Posts
    861
    Quote Originally Posted by MedicineMan25 View Post
    Can't edit so I'll just leave my solution here:

    I can't work out how to pass the address properly through to the display function, so I will just use the return as a NULL check. It will be as follows:

    Code:
    
    void list_disp_by_search(){
    
    
        for(int i = 0; search_arr[i] != NULL; i++){ <---- simplified
                printf(search_arr[i]->contact_name); <---incrementing index of array and access member of struct, which the pointer at desired index points to... 
        }
    
    
    }
    adding to what MedicineMan25 wrote
    Code:
    char *get_name_in_list_node(char *input_name)
    {
     mylist* search_arr = filelist_arr; // that is just so not  your stuff but the method ... 
     
    
     for(int i = 0; search_arr[i] != NULL; i++){
          if (strcmp(search_arr[i]->contact_name, input_name) == 0)
               return(search_arr[i]->contact_name);
         else
              return (NULL);
    }
    implmetation
    Code:
    char *bob = "billy";
    printf(%s\n", get_name_in_list_node(bob));
    ..//or
    
    if ( get_name_in_list_node(bob) == NULL )
    printf(' that dude is not listed. Yo!\n");
    else
    printf(%s\n", get_name_in_list_node(bob));
    
    //or to not make it look again, just assign the return to a char temp var and hold on to it, if it is valid then print it if not let it go.
    that looks like it will work. if you just want to do that other thing.

    yours
    Code:
    void *contact_travers_find(const char* contact_name)
    
    ....
      return &search_arr[0];
    how do you return a void pointer from a char and get something? or a list reference address or whatever that & does with pointers ( still trying to keep that in my memory banks) is that valid or .... should it not be like this
    Code:
    list  *contact_travers_find(const char* contact_name)
    I still don't like that other search function I did, , it don't look right, looks like it will keep returning NULL until found. if found (but stops on return sooo )
    Code:
    char *get_name_in_list_node(char *input_name)
    {
     mylist* search_arr = filelist_arr; // that is just so  not your stuff but the method ... 
     int i = 0;
    
     while ( search_arr[i]) {
          if (strcmp(search_arr[i]->contact_name, input_name) == 0)
               return(search_arr[i]->contact_name);
              i++;
    }
     
              return (NULL);
    }
    that one makes more sense to me.
    Last edited by userxbw; 09-23-2017 at 10:44 AM.

  5. #5
    Banned
    Join Date
    Aug 2017
    Posts
    861

    hate to be a bother , but...

    I'm just trying to understand your logic,
    Code:
    void *contact_travers_find(const char* contact_name){
     
     
        int name_length = strlen(contact_name);
        printf("name length = %d\n", name_length);
         
        for(int i = 0; i < 255; i++){
            search_arr[i] = NULL;
        }
         
        if (contact_tmp == NULL){    
            contact_tmp = contact_head;
        }
         
        bool name = false;
         
            if(contact_tmp != NULL){
                 
                int i = 0;
                 
                while(contact_tmp){ 
                     
                    name = (strncmp(contact_name, contact_tmp->contact_name, name_length -1) == 0);
                     
                    //printf("TEST %d\n", i++);
                     
                    if(!name){
                        printf("!name\n");
                        if(contact_tmp->next != NULL){
                            contact_tmp = contact_tmp->next;
                        } else {
                            printf("return search_arr[0] = %p \n", search_arr[0]);
                            return &search_arr[0]; //<----VRETURNING ADDRESS OF ARRAY MEMBER
                        }
                    } else if (name) {
                        printf("name\n");
                        search_arr[i] = contact_tmp;
                        printf("i = %d search_arr[i] = %p \n", i, search_arr[i]);
                        printf("contact_tmp = %p \n", contact_tmp);
                        i = ++i;
                        if(contact_tmp->next != NULL){
                            contact_tmp = contact_tmp->next;
                        } else {
                            printf("return search_arr[0] = %p \n", search_arr[0]);
                                return &search_arr[0]; // <---- RETURNING ADDRESS OF ARRAY MEMBER
                            }
                        }
                    } 
                 
                }
             
    }
    you are just looking for name. I've only did a list once, so just trying to understand. this is what I did to find a value within a member list not an array.

    Code:
    char *get_number_in_list(int numberfile)
    {
        int ln;
        mylist* current = filelist;
        ln = list_length(filelist);
    
    if(numberfile > ln)
    {
        printf("number ( %d ) larger than list length\n", numberfile);
        exit(1);
    }
    
    while (1)
    {
    
        if (current->listcount == numberfile)
        { // return kicks it out of function upon return.
            return(current->filename);
        }
    // keeps it cycling through list
       if(current->next)
         current = current->next;
        else
          current = filelist;
    
      }
    }
    check to be sure it is not going out of bonus of list then look for the value if not. because value is less than total size it has to be there, by the way I set it up to insert the number in the list members for each node. to get the name stored in node by number.

    you are looking for a name so that size thing is out. yet, what you are doing to me looks like over kill, or are you just doing all of that to see what it is doing to better understand it?

    this:
    Code:
      int name_length = strlen(contact_name);
        printf("name length = %d\n", name_length);
        
        for(int i = 0; i < 255; i++){
            search_arr[i] = NULL;
        }
    length of input name, null the array?

    why is that being done so I know.
    maybe learn something even. but you got char_len then
    how do you know it is 255?

    Code:
    for( int i = 0 ; array.length; i++)
    to not over or under run size of array.
    or
    Code:
    for ( int i = 0 ; i < name_length; i++)
       search_array[i] = null;
    but is that not emptying
    your array you want to search before searching it,
    or am I wrong?

    then it does not look like you're using it other then returning its &pointer off it through a void * and not a list * .. its confusing to me, but .. it's your code.
    Last edited by userxbw; 09-23-2017 at 11:18 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 12-20-2011, 09:43 PM
  2. array of pointers to structs
    By curiosita in forum C Programming
    Replies: 0
    Last Post: 04-30-2011, 04:08 PM
  3. Array of Pointers to Structs
    By I BLcK I in forum C++ Programming
    Replies: 3
    Last Post: 03-15-2008, 11:03 PM
  4. Array of pointers to structs
    By lpmrhahn in forum C Programming
    Replies: 1
    Last Post: 04-17-2004, 09:46 AM
  5. array of pointers to structs
    By stumon in forum C Programming
    Replies: 7
    Last Post: 03-24-2003, 07:13 AM

Tags for this Thread