Reputation: 7349
I'm a C beginner experimenting with linked lists and I found a Github repo for one. the create function is written like this:
Node* ListCreate(void* data) {
Node *head = malloc(sizeof(Node));
if ( head != NULL) {
head->next = NULL;
head->data = data;
}
return head;
}
I was able to use it by changing the void*
to int
and then in main
doing:
Node *root = ListCreate(5);
But then I read a little about void pointers and it seems like they can be used as generic types sort of like C++ templates, which would be useful if I could figure out how they work. I tried several things, and the closest I've got to getting it to work is no errors, but one warning:
incompatible integer to pointer conversion passing 'int' to parameter of type 'void *'
Am I missing a step here? I first felt like I should add something to the function definition, but I'm assuming the person who wrote it knows what they're doing and I just didn't use it properly in main
. So is there a different way I'm supposed to pass an argument to this function?
Upvotes: 1
Views: 3842
Reputation: 2730
As is mentioned by others in comment, it is more suitable to create different list for different types.
But if you want to use the same function definition, then use can pass the pointer to your data (int
or char
) and cast them as void *
.
/* main: start */
int main(void)
{
Node *list_head; /* Points to first element in list */
Node *node_tmp; /* Just a temporary pointer */
int *pint;
char *pchar;
/* create an empty list */
list_head = NULL;
/* Note that there is no error checking done for
* malloc, which is not good
*/
/* Create a node which points to int */
pint = malloc(sizeof(int));
*pint = 10;
node_tmp = ListCreate((void *) pint);
/* Add this node to list */
list_head = add(node_tmp, list_head);
/* Create a node which points to char */
pchar = malloc(sizeof(char));
*pchar = 'c';
node_tmp = ListCreate((void *) pchar);
/* Add this node to list */
list_head = add(node_tmp, list_head);
/* print total number of nodes in list */
print_tot_nodes(list_head);
return 0;
}
Code for add
and print_tot_nodes
ommited are for brevity.
Note, that functions like print_tot_nodes
or add
will have not much issues if data
points to different data types. But if you need to implement function like Node *smallest(Node *head)
, which returns pointer to the node having smallest element, then it may get complicated.
So, it is easier to use different list for different types. However you can cast
the actual pointer to some datatype to void *
if you need to use the same function definition as seen in your original post.
Upvotes: 1
Reputation: 40155
I think that there is a need to wrap for numeric literals(or cast?).
Like this:
void *BOX_VAR;//Not require if use GCC extension
#define BOX(type, value) ((*(type *)(BOX_VAR=malloc(sizeof(type))) = value), BOX_VAR)
#define UNBOX(type, value) (*(type *)(value))
Node *list = ListCreate(BOX(int, 5));
int v = UNBOX(int, list->data);
printf("%d\n", v);
Upvotes: 0