From: pereges on
Hi, I'm trying to create a generic link list. Here's the data
structure for node:
Code:

typedef struct node_s
{
void *data;
struct node_s *next;
}node;

Now let's say I want the data pointer to point to a vector structre:

Code:

typedef struct
{
double coord[3];
}vector;


I can assign data (of some random node in list) address of some
vector:

Code:

p->data = &v

p is pointer to node in link list and v is the vector.

But when I try an operation like this for eg:

Code:

p->data->coord[0] < p->data->coord[1]

It gives me an error. Is there any way I can solve this ?
From: pereges on
Btw this worked for me but I'm not sure if it is a legal or correct
way because it contradicts what i have have heard :

vector *a = (vector *) p->ptr;
vector *b = (vector *) p->ptr;

a->coord[0] < b->coord[0]
From: Francis Glassborow on
pereges wrote:
> Hi, I'm trying to create a generic link list. Here's the data
> structure for node:
> Code:
>
> typedef struct node_s
> {
> void *data;
> struct node_s *next;
>
> }node;
>
> Now let's say I want the data pointer to point to a vector structre:
>
> Code:
>
> typedef struct
> {
> double coord[3];
>
> }vector;
>
> I can assign data (of some random node in list) address of some
> vector:
>
> Code:
>
> p->data = &v
>
> p is pointer to node in link list and v is the vector.
>
> But when I try an operation like this for eg:
>
> Code:
>
> p->data->coord[0] < p->data->coord[1]
>
> It gives me an error. Is there any way I can solve this ? I have heard
> you can't typecast a void pointer to some other data type

Then you heard wrong. Indeed in C, (but not in C++) void* implicitly
convert to other data pointer types where the context provides the
necessary information (it doesn't in the code you provide)

However if you try to cast a void* to anything other than the original
type and then dereference the result you have undefined behaviour. IOWs
there must be an actual object of the correct type if you attempt to
dereference a pointer.


The error in your code is that a void* cannot be dereferenced.

If you want to access the data in your 'generic' linked list you need to
write something such as:

(vector)(p->data) -> coord[0]

However this is not the normal way to write a generic list in C. Instead
we would normally use a typedef. For example:

typedef int valuetype;

typedef struct node {
valuetype * data;
struct node * next;
} node;



Yes, this causes some problems if you want more than one type of linked
list in a single translation unit. But otherwise you can typedef the
valuetype before #include the header file that contains the relevant
declarations for your linked list.

From: Bart van Ingen Schenau on
pereges wrote:

> Hi, I'm trying to create a generic link list. Here's the data
> structure for node:
> Code:
>
> typedef struct node_s
> {
> void *data;
> struct node_s *next;
> }node;
>
> Now let's say I want the data pointer to point to a vector structre:
>
> Code:
>
> typedef struct
> {
> double coord[3];
> }vector;
>
>
> I can assign data (of some random node in list) address of some
> vector:
>
> Code:
>
> p->data = &v
>
> p is pointer to node in link list and v is the vector.
>
> But when I try an operation like this for eg:
>
> Code:
>
> p->data->coord[0] < p->data->coord[1]
>
> It gives me an error. Is there any way I can solve this ?

You get an error, because p->data is a 'pointer to void' and the type
void does not have a member called coord.

If you are using C++, the best solution is to make node a template:
template <class T>
struct node {
T data;
node* next;
};

In C, your only choice is to use a typecast:
((vector*)p->data)->coord[0] < ((vector*)p->data)->coord[1]

Bart v Ingen Schenau
--
a.c.l.l.c-c++ FAQ: http://www.comeaucomputing.com/learn/faq
c.l.c FAQ: http://c-faq.com/
c.l.c++ FAQ: http://www.parashift.com/c++-faq-lite/
From: Ben Bacarisse on
Francis Glassborow <francis.glassborow(a)btinternet.com> writes:

In the context of:
> pereges wrote:
....
>> typedef struct node_s
>> {
>> void *data;
>> struct node_s *next;
>> }node;
....
>> typedef struct
>> {
>> double coord[3];
>> }vector;
....
>> p->data->coord[0] < p->data->coord[1]
>>
>> It gives me an error. Is there any way I can solve this ?
....
> The error in your code is that a void* cannot be dereferenced.
>
> If you want to access the data in your 'generic' linked list you need
> to write something such as:
>
> (vector)(p->data) -> coord[0]

I imagine you intended to write:

((vector *)p->data) -> coord[0]

--
Ben.