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 *
Types int**
and void**
are not compatible
You are casting p, whose real type is int**, to void** and then dereferencing it here:
*((void **) p) = pv;
which will break aliasing rules.
You can either pass a void pointer and then cast it correctly:
void *pi = NULL;
int* ipi = NULL ;
allocate_memory(&pi, sizeof *ipi );
ipi = pi ;
or return a void pointer.
int *pi = allocate_memory(sizeof *pi);
There is an option to use a union:
#include
#include
#include
union Pass
{
void** p ;
int** pi ;
} ;
int allocate_memory(union Pass u , size_t s) {
void *pv;
if ( ( pv = malloc(s) ) == NULL ) {
fprintf(stderr, "Error: malloc();");
return -1;
}
printf("pv: %p;\n", pv);
*(u.p) = pv;
return 0;
}
int main()
{
int* pi = NULL ;
printf("%p\n" , pi ) ;
allocate_memory( ( union Pass ){ .pi = &pi } , sizeof( *pi ) ) ;
printf("%p\n" , pi ) ;
return 0;
}
As far as I understand it, this example conforms to standard.
Use static asserts to guarantee that the sizes and alignment are the same.
_Static_assert( sizeof( int** ) == sizeof( void** ) , "warning" ) ;
_Static_assert( _Alignof( int** ) == _Alignof( void** ) , "warning" ) ;