Reputation: 91
I've problem using void *. How should I do to use this clean_buffer function for int and float arrays.
void clean_buffer( void *ptr, int n)
{
for( int i = 0; i < n; i++)
ptr[i]=0;
}
int main(void)
{
float *pf;
int *pi;
pf = (float *) malloc(10*sizeof(float));
pi = (int *)malloc(10*sizeof(int));
clean_buffer( (float *)pf, 10);
clean_buffer( (int *)pi, 10);
return 0;
}
Upvotes: 1
Views: 400
Reputation: 153338
I've problem using void *. How should I do to use this clean_buffer function for int and float arrays (?)
Others have mentioned useful things like the need to sizeof
to find the size, cast not needed and alternatives to use calloc()
for a zero initialized memory allocation.
To add:
sizeof *object_pointer
Use sizeof *object_pointer
to find the size. It is less error prone, easier to review and maintain than coding in the type.
// clean_buffer( (float *)pf, 10);
// clean_buffer( (int *)pi, 10);
// cast not needed
clean_buffer(pf, sizeof *pf * 10); // No need to mention type!
clean_buffer(pi, sizeof *pi * 10);
volatile
Scrubbing memory after its final use is prone to being optimized out and then a good reason to not use memset()
when memory security is of concern. Instead use volatile
to prevent clean_buffer()
from itself being optimized out.
void clean_buffer(void *ptr, size_t n) {
volatile unsigned char *vuc = ptr;
for(size_t i = 0; i < n; i++)
vuc[i]=0;
}
}
Upvotes: 1
Reputation: 12404
Type void
has no size. Therefore you cannot use void *
to clear an array.
You can not dereference that type for the same reason.
You must cast to a pointer with specific type:
void clean_buffer(void *ptr, size_t n)
{
unsigned char *my_ptr = ptr;
for (int i = 0; i < n; i++)
my_ptr[i]=0;
}
You need to take care that the size passed to your function cannot be the number or arrays because the compiler cannot do pointer arithmetics with void*
pointers.
And for sizes you should use size_t
Instead you have to pass the size of the array in bytes:
int main(void)
{
float *pf;
int *pi;
pf = malloc(10*sizeof(float));
pi = malloc(10*sizeof(int));
clean_buffer( pf, 10*sizeof(float));
clean_buffer( pi, 10*sizeof(int));
return 0;
}
Or you need to pass any other information that can be used to determine type and/or size of the data.
Also:
Casting the return value of malloc
is not needed in C.
Casting the parameters of clean_buffer
to a type that the variable already has, is useless. The pointer type is converted to void *
anyway as this is what the function expects.
Note:
Other answers and comments mention that you could simply pass the pointer to memset
or use calloc
etc.
This might be true for this very specific case but if you want to do anything else than simply zeroing the memory, the same aspects regarding void *
pointers apply as I have shown here. And in those cases memset
or calloc
are of no help.
Upvotes: 2
Reputation: 24895
malloc
itself returns a void pointer as it doesn't really know for which type you are allocating memory. So, you need to use the same size which you pass to malloc
for clearing the buffer also.
You can use memset
and pass the size of the entire buffer to clear it without having to worry about it's type.
void clean_buffer( void *ptr, size_t n)
{
memset(ptr, 0, n)
}
int main(void)
{
float *pf;
int *pi;
pf = (float *) malloc(10*sizeof(float));
pi = (int *)malloc(10*sizeof(int));
clean_buffer(pf, 10*sizeof(float));
clean_buffer(pi, 10*sizeof(int));
return 0;
}
Additionally, as others have suggested, you can use calloc
if it suits you.
Upvotes: 0
Reputation: 1
void clean_buffer( void *ptr, int n)
This function demands a void * as a parameter.
clean_buffer( (float *)pf, 10);
Here you are casting to a float pointer. So this a different type as demanded
Also void has no size, so you cant really use [] on ptr
Upvotes: 0
Reputation: 32586
void is a non value you cannot use *((void*) x) = v;
and to use a cast to use a pointer to an other type is dangerous because the size may not be the same
But, in your case you set to 0, so you can use memset or replace the malloc my calloc and it is useless to have clean_buffer
:
int main(void)
{
float *pf;
int *pi;
pf = calloc(10, sizeof(float));
pi = calloc(10, sizeof(int));
return 0;
}
Upvotes: 2
Reputation: 49803
You cast ptr
to the appropriate type so it can dereferenced to clear what it points to; something you know points to a type that you want to clear i
items of.
Upvotes: 0