Search code examples
cpointersstructvoid-pointersabstract-data-type

void Pointer to a structure causes error 'dereferencing 'void *' pointer'


I try to initialize a queueADT pointer called initAmigo. Apparently I never create one if the structure is not making the pointers for the (void *data)

Reasons why I can't put any data in void *data in node structure:

Asuumption 1: Take away void *data and say User_struct (from .h file)

Assumption 2: RegisteredData is not supposed to be a pointer because the parameter in que_Insert asks for a pointer)

Assumption 3: In AddUser function, que_insert( initAmigo , registeredData); The registeredData to be inserted in the void *data node was actually a pointer to a pointer to a structure

Having a queue reference a void * creates the following error:

amigonet.c: In function 'findUser':
amigonet.c:247:21: warning: dereferencing 'void *' pointer [enabled by default]
   if (currNode->data->name == name) {  //If front is the name being searched
                     ^
amigonet.c:247:21: error: request for member 'name' in something not a structure or union
amigonet.c:253:22: warning: dereferencing 'void *' pointer [enabled by default]
    if (currNode->data->name == name ) {

.c file just has to create a structure of a queue of Users (QueueADT initAmigo)

typedef struct node {
                                    //name of data userStruct (just for referencing)
    void* data;
    struct node *next;
}node;


struct queueStruct {
    struct node *front;                             /* pointer to front of queue */
    struct node *rear;                              /* pointer to rear of queue  */
    int (*cmprFunc)(const void*a,const void*b);     /* The compare                                          function used for insert */

};

typedef struct queueStruct *QueueADT;       //typedef inserted for pointers, 
                                                //name is QueueADT

#define _QUEUE_IMPL_
#include "queueADT.h"

/// create a queue that is either sorted by cmp or FIFO
//function with two void
QueueADT que_create( int (*cmp)(const void*a,const void*b) ) {

    QueueADT new;
    new = (QueueADT)malloc(sizeof(struct queueStruct));     //NOTE: NO POINTERS HERE
                                                            //use pointers in Single lines
    if (cmp == NULL) {
        new->front = NULL;
        new->rear = NULL;
        new->cmprFunc = NULL;

    } else {
        new->cmprFunc = cmp;
        new->front = NULL;
        new->rear = NULL;
    }
    return ( new );
}

//free the queue once the nodes have been cleared from the queue
void que_destroy( QueueADT queue ) {
    if ( queue->front == NULL ) {
        free(queue);
    } else {
        que_clear(queue);
        free(queue);
    }
}

//passes a real pointer for dynamic allocation
//set a temp to the front to be deleted, then front becomes the next and delete the temp

void que_clear( QueueADT queue ) {


    while (queue->front->next != NULL) {
        struct node *temp;
        temp = (struct node*)malloc(sizeof(struct node));
        temp = queue->front;
        queue->front= queue->front->next;

        free(temp);
        }
}


//if the cmpr function returns a positive then put in in before the b node in cmp(curr, temp)   
void que_insert( QueueADT queue, void *data ) {
    struct node *temp;
    temp = (struct node*)malloc(sizeof(struct node));
    temp->data= data;
    temp->next = NULL;
    node *currNode;             //simply a pointer
    currNode = queue->front;
    if ( queue->front != NULL ) {               //+1 or more in Q
            if ( queue->cmprFunc == NULL ) {        //if the cmp_func is FIFO

                queue->rear->next = temp;
                queue->rear= temp;
                queue->rear->next=NULL;
                if ( queue->front == queue->rear ) {
                    currNode->next = temp;
                    queue->rear = temp;
                    temp->next= NULL;
                    }
            } else {

                while ( currNode->next != NULL ){       //2 or more
                    if (( (*(queue->cmprFunc))(currNode->data, temp->data) >= 0 
                           && ( currNode == queue->front)) ) {
                            temp->next = currNode;
                            queue->front=temp;
                            break;
                            }
                    if (( (*(queue->cmprFunc))(currNode->next->data, temp->data) >= 0 ) ) {             

                            temp->next = currNode->next;
                            currNode->next = temp;
                            break;
                    } else  {
                        currNode = currNode->next;          //move past front and possibly rear
                        if (currNode->next == NULL )  {     //currNode is rear of queue
                            currNode->next = temp;
                            queue->rear = temp;
                            temp->next = NULL;
                            break;
                        }
                                            //exit_failure  
                    }
                }
                if ( queue->front == queue->rear ) {        //exactly 1 node in queue

                    if (( (*(queue->cmprFunc))(currNode->data, temp->data) >= 0 ) ) {

                            temp->next = queue->front;
                            queue->front = temp;
                        } else {

                            queue->front->next = temp;
                            queue->rear = temp;

                        }
                    }
            }
    } else {                                            
        queue->front = temp;
        queue->rear= queue->front;
        queue->front->next= queue->rear->next = NULL;

        }
    }


//removes the front
void *que_remove( QueueADT queue ) {
    if ( queue->front != NULL ) {       //if the size of queue is greater than 1
        node *currNode;                 // dont make new node, pointer
        currNode = queue->front;
        void *data = currNode->data;
        if ( queue->front == queue->rear ) { //if size of queue is 1
            free(currNode);
            queue->front = queue->rear = NULL; //set both to NULL
        } else {
            queue->front= currNode->next;
            free(currNode);
        }
        return data;    
    }
    return NULL;
}

bool que_empty( QueueADT queue ) {
    if ( queue->front == NULL ) {
        return true;
    } else {
        return false;
        }
}


QueueADT initAmigo; 

//struct queueStruct *initAmigo
//QueueADT initAmigo;

//make a Queue with front and rear
    //compare function with A-Z

struct Friends_struct {
    struct queueStruct *amigos_Queue;
};  


void create_amigonet() {
    //makes the same thing as que_Create 
    //(Friends)malloc(sizeof(struct Friend_struct));

    initAmigo = que_create(NULL);
    printf("%lu Founded size of an.c\n\n\n\n\n\n\n\n\n\n\n", sizeof(initAmigo));
}


//The add user will find a new user and make the name of the user to a amigonet
//add Usernode to queue initAmigo
//make sure set to first and display queue

void addUser( const char *name ) {
    //create Usernode and void *data (user w/ friends)
    //check to see if User already exists
    if ( findUser(name) != NULL) {
        return;
    }
    //create data for node, by initializing memorry for a userStruct
    struct User_struct *registeredData;
    registeredData = ( struct User_struct* )malloc(sizeof(struct User_struct));     //first user Data

    registeredData->name = name;

    //create a Friends
        //put this in file create F
    struct Friends_struct *initAmigos;
    initAmigos = (struct Friends_struct*)malloc(sizeof(struct Friends_struct));     //NOTE: NO POINTERS HERE
    //set Friends list to Null
    initAmigos->amigos_Queue = que_create( NULL );

    //put User with empty Friends struct
    registeredData->amigos = initAmigos;

    //void que_insert( QueueADT queue, void *data )
    que_insert( initAmigo , registeredData);
    printf("%s User was inerted \n", name);

}
//Find a user in the init Amgio
//start at front as temp, go to next until name found

User *findUser( const char *name ) {
    struct node *currNode;
    currNode =  initAmigo->front;
    printf("%lu Founded size of an.c\n\n\n\n\n\n\n\n\n\n\n", sizeof(initAmigo));
    if ( initAmigo->front == NULL ) {
        return NULL;
    } else {
        if (currNode->data->name == name) {  //If front is the name being searched
            return currNode->data;
        }
               //Loop after front 
        while ( currNode->next != NULL ) {
            currNode = currNode->next;
            if (currNode->data->name == name ) {
                return currNode->data;
            }
        }
        node *rear = currNode;
        if (rear->data->name == name ) {
            return rear->data;
        }
    }
    //User Not Founded
    return; 
}
#if 0
void addAmigo( User *user, User *amigo ) {

    //check to see if node exits within friends
    //go to use friends list
    //traverse the node, check data for amigo->name == data->name

    if (  user->amigos->amigos_Queue->front != NULL ) {
        node *currNode = user->amigos->amigos_Queue->front;
        if ( currNode->data->name == amigo->name ) {
            return ;
        } else {
            //loop to determine if User friend  queue front to rear has amigo already
            while ( currNode->next != NULL ) {
                currNode = currNode->next;
                if (currNode ->data->name == amigo->name) {
                    return;
                }
            }
        }
    }
    que_insert( user->amigos->amigos_Queue, amigo);
}


void removeAmigo( User *user, User *ex_amigo) {
    //Pre Condition: Amgio exists in user


    //go to user
    //set user as currNode


    //either create a function in queueADT remove
    // use a prev and curr and next and traverse, remove, connect
    //preconditions: front is not examigo
    //   rear is not examigo
    // amigo is friend of user

}


size_t separation( const User *user1, const User *user2 ) {

    return;
    //queue a DFS
    // queue a BFS
    //  
}
//search using a queue BFS
//search using a DFS

//number of users and their names
void dump_data() {
    if (initAmigo->front != NULL) {
        node *currNode = initAmigo->front;
        printf("%s: Amigos!\n", currNode->data->name);      //prints the name of the first node
        while ( currNode->next != NULL ) {
            currNode = currNode->next;
            printf("%s: Amigos!\n", currNode->data->name);
        }
    //while loop of each user set to currNodw

    //set a variable for currNodeAmigo and print the names of them inside ^^^
    }
}

void destroy_amigonet(){
    //clear Friend Queue and destroy for each User Friend
    //destroy initAmigo queue
}

Solution

  • The problem looks like this:

    typedef struct node {
      void* data;
      struct node *next;
    }node;
    
    ...
    
    struct node *currNode;
    
    if (currNode->data->name == name) {  //If front is the name being searched
        return currNode->data;
    }
    

    The type of currNode->data is void *. This is an incomplete type, which means that it cannot be dereferenced. The compiler has no idea what to make of whatever it points at. You need to convert the void pointer, into a pointer to a meaningful type.

    You have not defined the User type in the code you posted, but I'm guessing that you want something like this:

    User *user = currNode->data;
    
    if (user->name == name) {
        return user;
    }
    

    You will also have to make similar changes elsewhere in the same function.