Thread: How to access a field of struct pointed by pointer pointed by pointer ecc...

  1. #1
    Registered User
    Join Date
    Feb 2018
    Posts
    21

    How to access a field of struct pointed by pointer pointed by pointer ecc...

    Hello guys, sorry for this horrible title. I have a big problem.
    I created my first personal Generic Singly Linked List. This is code (in italian Lista = List):
    Code:
    typedef struct Node {
        void *data;
        struct Node *next;
    }Node;
     
    typedef Node* iterator;
    
    typedef struct Lista {
        Node *head;
        Node *tail;
        int length;
    }Lista;
    and this is function that insert an element at start:

    Code:
    void Insert(Lista *lista, void *data) {
        Node *n = New_Node(data);
        n->next = lista->head;
        lista->head = n;
    }
    this is my New_Node function:
    Code:
    Node *New_Node(void *data) {
        Node *n = malloc(sizeof(*n));
        n->data = data;
        n->next = NULL;
        return n; 
    }
    Ok, this code stayed in Lista1.c file.

    Now, I need to use this code into another program, like "HashTable.c", so in HashTable.c I have insert:
    Code:
    #include "C:/Users/MYUSER/Documents/C/Lista1/Lista1.c"
    Also in HashTable program, for testing, I imagined to have this struct:
    Code:
    typedef struct Contact {
        char *name;
        int number;
    }Contact;
    Everythings works fine, I can create my List and I can call Insert function (I had to remove the main from Lista1.c, only in this way all worked fine), but the problems start when I must write my Have_Name function, because I can't reach the field which I need and I don't understand why!
    Code:
    bool Have_Name(Lista *lista, char name[]) { // lista is not empty! I fill it with Insert function!
        iterator ite = lista->head;
        for (int i = 0; i < lista->length; i++) {
            if (Equal(ite->data->name, name))       <--!!Problem here!!
                return true;
            else
                ite = Next(ite);
        }
        return false;
    }
    
    bool Equal(char a[], char b[]) {
        int i = 0;
        int lengthA;
        int lengthB;
        while(a[i] != '\0') {
            lengthA++;
            i++;
        }
        i = 0;
        while(b[i] != '\0') {
            lengthB++;
            i++;
        }
        if (lengthA != lengthB)
            return false;
        else
            for (int i = 0; i < lengthA; i++) {
                if (a[i] != b[i])
                    return false;
            }
        return true;
    }
    I call this function in this way:
    Code:
        int key = Hash_S(testName);
        if (Have_Name(&array[key], testName))
            printf("The list have the name!\n");
    where my array of list is created in this way:
    Code:
        Lista *array = malloc(sizeof(*array) * 5);
        for (int i = 0; i < 5; i++)
            array[i] = *New_List();
    Now,
    Why doesn't ite->data->name return contact's name?
    ite->data should return the pointer that point my "Contact" struct, and ite->data->name should return contact's name, right?
    I tried to write also a cast action like java style, but without results..
    Code:
    ((Contact) ite->data)->name
    (Once again, sorry for my bad english..)
    Pls help me!
    Last edited by Jacopo; 03-06-2018 at 05:05 AM.

  2. #2
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,742
    'data' is a void pointer so you have to cast it to a pointer to the type that you've actually stored there. From a quick glance it seems you're storing an object of type struct Contact there (if it's something else and I've misunderstood then everything still applies, just use the correct type). So to access the 'name' member of that you need
    Code:
    if (Equal(((Contact *)(ite->data))->name, name))
    Edit: Oops I didn't see the last few lines of your post. You were almost there but you needed to cast to "pointer to Contact" not Contact; i.e. (Contact *) or (struct Contact *) if you don't want to use the typedef
    Last edited by Hodor; 03-06-2018 at 05:41 AM.

  3. #3
    Registered User
    Join Date
    Feb 2018
    Posts
    21
    Quote Originally Posted by Hodor View Post
    'data' is a void pointer so you have to cast it to a pointer to the type that you've actually stored there. From a quick glance it seems you're storing an object of type struct Contact there (if it's something else and I've misunderstood then everything still applies, just use the correct type). So to access the 'name' member of that you need
    Code:
    if (Equal(((Contact *)(ite->data))->name, name))
    Edit: Oops I didn't see the last few lines of your post. You were almost there but you needed to cast to "pointer to Contact" not Contact; i.e. (Contact *) or (struct Contact *) if you don't want to use the typedef
    A week lost for this..Thank you so much sir! I love this place!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 7
    Last Post: 11-10-2012, 08:56 PM
  2. resizing array pointed to by pointer
    By sys_x in forum C++ Programming
    Replies: 3
    Last Post: 12-27-2008, 12:06 PM
  3. Problem with passing back pointer pointed to string
    By whichet in forum C Programming
    Replies: 9
    Last Post: 11-21-2007, 07:55 AM
  4. changing the value pointed to by a pointer
    By peterchen in forum C Programming
    Replies: 7
    Last Post: 06-16-2006, 07:49 AM
  5. Replies: 5
    Last Post: 10-29-2001, 10:16 AM

Tags for this Thread