Is this valid/proper code, or does it violate standards -- possibly invoking undefined behavior (UB)?
--> Specifically, the cast of void *
to char **
in foo()
. <--
It does work, but we know that 'working' isn't good enough.
And any other errors, please rip it up and post corrected code if you like, please.
#include <stdio.h>
#include <stdlib.h>
#define SIZE 5
void foo(void *vp)
{
char **dp = (char **)vp;
int i;
for(i=0; i<SIZE; i++)
{
printf("%s", dp[i]);
}
}
int main()
{
char **dp;
int i;
dp = malloc(SIZE * sizeof(char *));
for(i=0; i<SIZE; i++)
{
dp[i]= malloc(20);
sprintf(dp[i],"Now: %d\n",i);
}
foo(dp);
return 0;
}
Output:
Now: 0
Now: 1
Now: 2
Now: 3
Now: 4
I tried foo(void **vp)
which seems right to me but does not compile. Conversely, foo(void *vp)
seems wrong(?) but compiles and works. I've not been concerned with trivialities like this until now, as I am wanting to take my C to the next level.
A void *
is essentially a generic pointer type. Any object pointer type, regardless of how many "levels" that pointer is, may be converted to a void *
and back without a cast.
Because of this, the conversion from void *
to char **
is not only safe but the cast is unnecessary.
Trying to use void **
doesn't work because the special treatment given to void *
doesn't carry over to a void **
. A void **
is a specific type: a pointer to a void *
.