error accessing/using void pointers in c - c

So I have this Linked List print function that is giving me the error:
error: invalid use of void expression
Here's the line that causes this error:
printf("[%d] -> ", *(link->pointer)); /*note: i tried to cast it to (int) but still same error. */
Here's my struct for the link; very straight forward:
typedef struct DLLNode {
void * pointer;
struct DLLNode *next;
struct DLLNode *previous;
} DLLNode;
I'm using my prepend function as so:
...
int j = 2;
prepend(&j, list);
...
so that it uses the pointer to variable two as the value the struct stores in new DLLNode as the pointer.
Could someone tell me why this is happening and what it means? Thanks for your time.

I suppose you are trying to print the value that link->pointer points to.
printf("[%d] -> ", var) expects to see either an integer in its argument list or something that can be converted to it (for example, a char).
link->pointer is of type void * and after dereferencing, it looks like a void type variable. Thus, compiler can't convert *(link->pointer) to int type. To tell it that you actually keep an integer value behind that void * pointer you need to explicitly convert link->pointer to a int * type, as Kaz pointed out in the comments and only then dereference it. I hope the following code demonstrates this more clearly:
DLLNode *list;
// initialization and other stuff
void *p = list->pointer;
int *p_i;
p_i = (int*)p; // explicit cast to int*
// print the integer value pointed to by the list->pointer
printf("[%d] -> ", *p_i);

Related

Getting the value inside a pointer pointed by another pointer?

I have a queue that stores thread structures
struct x
{
int n;
char *c;
void *f;
};
The function below returns a structure defined as the following:
struct s {
void *data;
};
When I call *new = allocate(&x_ptr), how can I access the members of x?
I tried the following but it does not work:
printf("%d\n", new ->data->n)
I get this error: request for member ā€˜nā€™ in something not a structure or union
data has type of void *, you need to cast it to the correct pointer type (assuming it is referencing a valid object of that type).
printf("%d\n", node->data->threadid);
---->
printf("%d\n", ((threaddesc *)(node->data))->threadid);

What does the notation (((nodeptr) (bodyptr)) -> type) mean in C?

I came across a piece of code that looks like this, where nodeptr and bodyptr are pointers to a struct, and type is a member of the struct.
#define Type(x) (((nodeptr) (x))->type)
What does it mean to have two pointers next to each other in brackets? I get that the -> notation gets the member of the struct, but am not sure about the first part of the line. I'm fairly new to C and am trying to get my head around pointers!
It's a cast.
In this part, ((nodeptr)(bodyptr)), The pointer bodyptr is casted as pointer of type nodeptr, then it accesses the member type of the structure pointed to by bodyptr.
I.e.
void *GetStructPtr(void); //The function returns a pointer to void
typedef struct //This is our structure
{
float a;
int type;
} node;
type def node *nodeptr; //This is our pointer type
void my func(void)
{
void *bodyptr; //Here we have a generic void pointer
bodyptr = GetStructPtr(); //Assign to it the vallue returned from function
//In the next line we cast our void* to a pointer to a structure node
//and then access its member type.
((nodeptr)bodyptr)->type = 0;
}
In your case it has been inserted in a macro to make it easier to use.
It is cast. The pointer bodyptr is being casted to nodeptr and then type member accessed. This means that instead of accessing type member directly from bodyptr it is first converted to pointer of type nodeptr and only then accessed. It is useful e.g. when first pointer is just a pointer to raw memory, of type void * and you want to treat this memory as given type, maybe some struct.
Example:
struct e {
int a;
double b;
};
struct e foo { 1, 2.0 };
void *pFoo = &foo; // p points at foo now
// I know p is now address of object of type struct e
// and I want to get it's 'a' element BUT I can't
// do p->a, p is of void* type, yet I can do
int a = ((struct e*)(pFoo))->a;

a value of type "void" cannot be assigned to an entity of type "void(*)(struct *Queue, int)

I've the following struct:
typedef struct{
int *arr;
int maxSize, curSize;
int first, last;
int(*isEmptyFunc)(Queue);
int(*isFullFunc)(Queue);
void(*EnqueueFunc)(struct Queue*, int);
void(*DequeueFunc)(struct Queue*);
int(*TopFunc)(Queue);
} Queue;
And a create queue function that returns a pointer to a new queue:
int *arr = malloc(sizeof(int) * size);
isNull(arr);
Queue *q = malloc(sizeof(Queue));
isNull(q);
When I try to assign values to the function pointers, I do:
(It all happen in the CreateQueue function)
q->isEmptyFunc = isEmpty(*q);
q->isFullFunc = isFull(*q);
q->TopFunc = Top(*q);
q->DequeueFunc = Dequeue(q);
The actual functions are declared in a header file I included in the top of the .c file, and implemented just below the CreateQueue func.
The first three assignments seem to be fine, but for the fourth the compiler screams:
IntelliSense: a value of type "void" cannot be assigned to an entity of type "void (*)(struct Queue *)"
The Dequeue function implementation is:
void Dequeue(Queue *q) {
if (q->isEmptyFunc()) return;
q->first = (q->first + 1) % (q->maxSize);
q->curSize--;
}
What's going on here?
The major problem here is, isEmptyFunc, isFullFunc, EnqueueFunc and DequeueFunc, all are function pointers. You're trying to put a return value of a function call, (here, which is not a function pointer, we can assume). That is completely wrong. It is not fine and you should not be doing that.
Now, if we see, in your case
The first three assignments seem to be fine,
The compiler does not complain here, because all the three function calls return some value (possibly int?) and that is implicitly converted to the function pointer type, however, the behavior is not defined. You must not do that.
but for the fourth the compiler screams:
in that case, the Dequeue() function return type is void, which cannot be used as a value. So, the compiler is (thankfully) complaining.
TL;DR you need to change all those above statements.

Assign value at pointer value from void pointer

I have two void pointers inside structures.
typedef struct DATA_T {
BOOLEAN trigger;
void *var_p;
void *data_p;
} DATA_T;
typedef struct ITEM_T {
DATA_T job_data[100];
BOOLEAN job_active;
BOOLEAN job_send;
} ITEM_T;
ITEM_T foo[100];
I assigned the two void pointers to different addresses. Now, I have a value at one pointer and want to set the other pointer = to that value.
foo[i].job_data[j]->data_p = *(int*)foo[i].job_data[j].var_p;
This error is then posted:
error C2232: '->data_p' : left operand has 'struct' type, use '.'
I don't believe I want a . in place of the -> here, because I need to dereference the pointer data_p.
Thanks for your assistance.
The error message is because job_data[j] is not a pointer. It is a DATA_T. So the left-hand side should be foo[i].job_data[j].data_p = .
However there is another error. On the right-hand side, *(int *) produces an int, which cannot be stored in a void *.
If you want to make the two pointers point to the same place then remove the *(int *).
If both pointers actually point to ints, and you want to copy the pointed-to value on both sides, then put *(int *) on both sides.
Elements of job_data array are not pointers, they're in the type of DATA_T.

convert list to struct

I'm trying to write a process table for my forks. I've got a global table and every process has to be written into this table.
I've got the struct
typedef struct {
int pid; /* Prozess ID */
char* name; /* Prozess Name (Programm) */
char* status; /* Status des Programms */
int check; /* bereits abgerufen? 1 - abgerufen, 0 - nicht abgerufen */
} Pstatus;
Listen:
typedef struct liste {
void *kopf;
struct liste *rest;
} *Liste;
listeKopf:
void* listeKopf(Liste l) {
if(l==NULL)
abbruch("listeKopf(listeLeer) undefiniert");
return l->kopf;
}
listeAnfuegen:
Liste listeAnfuegen(Liste l, void* element){
Liste neu=reserviere(sizeof (struct liste));
neu->kopf = element;
neu->rest = l;
return neu;
}
I'm writing my processes into the list using struct Pstatus. When I'm trying to read from my list I get the error: conversion to non-scalar type requested in line 284
my code is here:
http://pastebin.com/xEDvLTQk
Is somebody able to help me?
So Liste is a generic list that can hold references to anything via a void * pointer, right? And listeKopf returns that pointer.
According to your definition, Pstatus is a struct, not a pointer to struct, so you can't convert to it from void *. You also shouldn't be able to access its members with the -> operator, only with the dot . syntax.
(As a matter of personal taste, I prefer not to typedef pointer types, so that you can see whether a variable is a pointer or not by looking at the stars in the code.)
I looked at your code, basically on your line 284, you have this expression:
p = (Pstatus) listeKopf(temp);
the p is just the Pstatus struct variable and your listeKopf(temp) returns (void *kopf) which can not be assigned to a non-scaler variable( it should be assigned to a pointer).
you should change your code to look like this:
Pstatus *p
p = listeKopf(temp);
to avoid the error you are getting and also the cast to Pstatus is not needed as void * can be assigned to any pointer type.
Scalar types in C:
Arithmatic Types
Pointer Types
I hope it helps.

Resources