Reputation: 724
I need to compare the values of two void
pointers in C. In the code below, I'm getting the console print out that they are different. It seems that the comparison is between the addresses contained in these two void
pointers.
How can I make it so that the code compares values (ie: 1 == 1
) of the void
pointers and prints "same"
?
int main(void)
{
int i = 1;
int j = 1;
void *pi = &i;
void *pj = &j;
if (pi == pj) {
printf("same.\n");
} else {
printf("different.\n");
}
return 0;
}
Upvotes: 4
Views: 23158
Reputation: 46960
The pointers are different. If you are trying to compare the integers the pointers point to, then you want
if ( *(int*)pi == *(int*)pj ) {
//some code...
}
Upvotes: 2
Reputation: 2130
From your comments, you are tryng to implement a linked list and do not know the data type of the targets of the pointers. Your design is wrong: with void*
pointersyou simply cannot (reasonably or reliably) compare the data without knowing the type. You need to approach it differently. The best approach is to implement the linked list as a template class. Your node class will look something like
template <typename T> class Node
{
private:
T *m_pValue;
Node *m_prev;
Node *m_next;
...
}
But be aware that you need to be very careful of memory management. You need to decide who is going to own and manage the objects. In the class above, the user must manage the objects completely. If you want to relieve the user of this burden, use autopointers, so your nodes become something like
template <typename T> class Node
{
private:
std::auto_ptr<T> m_pValue;
Node *m_prev;
Node *m_next;
...
}
In both cases, you can compare the values via
Node rhs, lhs;
*(lhs.m_pValue) == *(rhs.m_pValue);
and this simply presumes that the T type can be compared via ==, which should be true in most cases.
Note that the suggestions of using memory compare and the like are just dangerous - such comparisons completely ignore the structure and symantics of the underlying data type.
OK, given that this must be in C, make your nodes like
struct node
{
void * m_pValue;
node * m_pPrev;
node * m_pNext;
}
and require that the user of your linked list must provide you with a pointer to a comparitor function
int (comparitor*)(void* lhs, void* rhs);
which is exactly what Jonathan Leffler suggested below. Exactly how to structure all this depends on how your are structuring your linked list.
Upvotes: 1
Reputation: 754080
You have to know what type of data the void
pointers really point at, coerce the pointers to point to that type, and then dereference the coerced pointers (and assume that the types are comparable using ==
):
if (*(int *)pi == *(int *)pj)
printf("same.\n");
else
printf("different.\n");
It's a lot easier just to compare the original variables:
if (i == j)
…
or to use correctly typed pointers:
int *pi = &i;
int *pj = &j;
if (*pi == *pj)
…
What happens in the case that I do not know the type of data (assuming that an user will always pass the same type of data to be compared with my linked list delete method)?
Then life gets difficult. Ideally you get the programmer to pass you a comparator function — see bsearch()
and
qsort()
from the Standard C library for examples.
Failing that, you need to know the size of the target type and you hope that memcmp()
will do the job sufficiently well. That's far from guaranteed — it is not clear that comparing two double
values with memcmp()
will always produce the correct answer (it might claim different representations of NaN are different, for example), and comparing struct
types with padding is fraught, and it wouldn't work correctly for your linked list data type if you're passed the nodes (it might be OK if you're passed the data fields from the two nodes).
If you needed to do ordering rather than just equality (a binary search tree, for example), then the situation is worse — in that case, require the programmer to supply the comparator function.
Upvotes: 6
Reputation: 12270
u have to type cast the void pointer to type int*
as the compiler doesnt know what type of address the pointer is pointing at, it doesnt know how many bytes to read from the pointer address and compare. try this
int i = 2;
int j = 1;
void *pi = &i;
void *pj = &j;
if ( (*(int*)(pi)) == (*(int*)(pj)) )
{
printf("same.\n");
} else
{
printf("different.\n");
}
return 0;
Upvotes: 1