C - (void *) to int

I implement a simple priority queue in C for the kernel, so I cannot use standard libraries. The queue contains the head of the node, and each node points to the next in the queue.

typedef struct node node; struct node { node *next; void *data; }; typedef struct { node *head; int n; } queue; 

As you can see, each node stores data in a void *. I am having trouble converting this data to say int when I pop the data from the stack.

 //push data int int_data = 100; push(q, &int_data); //... //pop data node* popped = pop(q); int *pop_data = popped->data; printf("pop data (100): %d\n", *pop_data); 

Why can't I get the original value here? I seem to be typing the value of a pointer. Alternatively, is there a better way to handle this?

== edit (sorry, should have included them):

 void push(queue *q, void *data) { node new; new.data = data; node *new_ptr = &new; if(is_empty(q)) { q->head = new_ptr; q->n++; return; } int i; node *curr = q->head; for(i=0; i<q->n; i++) { curr = curr->next; } curr->next = new_ptr; q->n++; } node* pop(queue *q) { node *curr = q->head; q->head = curr->next; return curr; } 
+4
source share
4 answers

Is your code in one function? If not, int int_data flies out of the stack (not your turn, the actual stack), which is probably the reason that you are printing garbage; you save the address of a local variable.

I would suggest changing void* data to int data . (If you need to, you can save the address in int and return it to a pointer later.)

 int int_data = 100; push(q, int_data); node* n = pop(q); int num = n->data; 

After reviewing the code again, you have the same problem when adding a new node. node new goes out of scope at the end of the function, so basically all of your nodes in your queue point to invalid memory.

+4
source

If the pop operation is in another function:

The problem is probably due to the fact that you are pushing the local variable in turn.

When you go to pop, that address is no longer valid (or at least doesn't indicate an int value), so you are typing something strange. Since the data no longer points to your int, it probably looks like a memory address.

+3
source

Do you set data = int_data (i.e. int β†’ void *) or data = &int_data (i.e. int * β†’ void *)? In the first case, you need to write printf("pop data (100): %d\n", pop_data);

0
source

You can use the glib macro GPOINTER_TO_INT :

 #define GPOINTER_TO_INT(p) ((gint) (glong) (p)) 

But please pay attention to the note to the document:

YOU MAY NOT DELETE ORDERS OF INTEGERS. THIS IS NOT PORTABLE IN ANY FORM FORM OR FORM. Only these macros allow integers to be stored in pointers, and only 32 bits of an integer are stored; values ​​outside the range of the 32-bit integer will be distorted.

0
source

Source: https://habr.com/ru/post/1339922/


All Articles