Andreas <an*************@gmail.comwrote:
Jens Thoms Toerring skrev:
Andreas Vinther <an*************@gmail.comwrote:
I have a small piece of code that compiles but does not perform like I
want it to.
void **y;
int i = 0;
*y = malloc(5 * sizeof(void*));
You assign to something 'y' is pointing to, but since 'y' isn't
initialized things go badly wrong. Moreover, you try to assign to
a void pointer something that points to a set of 5 void pointers -
That is what I want it to do. I want a void pointer that points to 5
other void pointers.
Mmmm, you might think so, but if you really think about it again you may
find that you don't want that. And you may be misled a bit by the malloc()
returning a void pointer and the automatic conversion from void pointers
to any other types of pointers. But you better think about the problem not
in terms of void pointers etc. but instead of some "real" data type. Let's
say you want an array of int pointers. Then you would have
int **x;
x = malloc(5 * sizeof *x); /* or x = malloc(5 * sizeof(int *)); */
and probably wouldn't come up with the idea that 'x' should be an int
pointer but that it must be a pointer-to-pointer to int. I.e. the thing
on the left hand side of the assignment must be a pointer to what you
want allocate memory for, so if you want to allocate memory for a set
of pointers to int you need a pointer-to-pointer to int. And in exactly
the same way you should go about dealing with void pointers and poin-
ters-to-pointers to void. While those may look indistinguishable at the
first glance they are of different type.
Ofcourse...that's it.. Stupid me I haven't initialised it yet. So if I add:
void *x
y = &x;
to my original code it should work.
It might work but all for the wrong reasons;-) If you need memory
for a set of values (I avoid the word 'array' here, since an array is
a bit more than just a collection of consecutive values in memory),
be ints, doubles or pointers, the type of a pointer to this "set" is
pointer to the type of the elements of this set. So if you want a set
of void pointers than a pointer to this (what you get from malloc())
must be of type pointer-to-pointer to void, not just void pointer. And
hat's why using
void **y;
y = malloc(5 * sizeof(void *)); /* or y = malloc(5 * sizeof *y); */
is the right way (even if it may be a bit hard to see when you insist
on thinking in terms of void pointers only and not also types).
Moreover, if you would use
void *x;
void **y = &x;
*y = malloc(5 * sizeof(void *));
then using 'y' later is going to be real tricky because 'y' won't be
a pointer-to-pointer to void (as you told in its definition) but a
pointer-to-pointer-to-pointer to void. If you lie to the compiler and
want to get away with it you must know very well what you're doing,
otherwise it will get its revenge;-)
You probably will get some compiler warnings for these attempts if
you raise its warning level - if 'y' is a pointer-to-pointer to void,
then y[i] is of type pointer to void, and thus assigning to *y[i] or
*(y[i]) (which is the same, the [] binds more tightly than the de-
reference operator *) would mean you try to assign a value to a void,
which of course isn't allowed.
I'm aware of that... but I intend to typecast my void pointers to other
pointers... But at this stage in the code I do not yet know what
datatype the pointer wil point to. An example could be:
*((double *)y[i]) = double_value; //if it's of type double
I think that is a legal aproach
While in principle it is (but only if 'y' is really a pointer-to-
pointer to void and not a "triple" pointer) this looks a bit like a
maintenance nightmare in the making. Why insist on using void pointers
etc. when you already know the type of what you're going to store?
Except in special cases I found it to be better for my mental sanity
(as far as any is left;-) to use the correct types wherever possible
and not to obfuscate what's happening by the use of "generic" pointers
and casts. As a rule I try to avoid situations where casts are needed -
often they just show that one hasn't really understood what's going on
and instead of thinking clearly is groping in the dark for some
"solution" that might seems to work (but, alas, often not really does).
Regards, Jens
--
\ Jens Thoms Toerring ___
jt@toerring.de
\__________________________
http://toerring.de