It is common to assign pointers with allocations using an implicit function-return void * conversion, just like malloc()'s:
void *malloc(size_t size);
int *pi = malloc(sizeof *pi);
I would like to perform the same assignment while passing the address of the target pointer, and without explicitly casting its type from within the function (not within its body, nor arguments).
The following code seems to achieve just that.
.
#include <stdio.h>
#include <stdlib.h>
int allocate_memory(void *p, size_t s) {
void *pv;
if ( ( pv = malloc(s) ) == NULL ) {
fprintf(stderr, "Error: malloc();");
return -1;
}
printf("pv: %p;\n", pv);
*((void **) p) = pv;
return 0;
}
int main(void) {
int *pi = NULL;
allocate_memory(&pi, sizeof *pi);
printf("pi: %p;\n", (void *) pi);
return 0;
}
Result:
pv: 0x800103a8;
pi: 0x800103a8;
No, this is not compliant. You're passing an int**
as void*
(ok), but then you cast the void*
to a void**
which is not guaranteed to have the same size and layout. You can only dereference a void*
(except one gotten from malloc
/calloc
) after you cast it back to the pointer type that it originally was, and this rule does not apply recursively (so a void**
does not convert automatically, like a void*
).
I also don't see a way to meet all your requirements. If you must pass a pointer by pointer, then you need to actually pass the address of a void*
and do all the necessary casting in the caller, in this case main
. That would be
int *pi;
void *pv;
allocate_memory(&pv, sizeof(int));
pi = pv;
... defeating your scheme.