Transferring values from void pointer
Can someone tell me whats wrong with this code?
base
is a void pointer to a bunch of floats
i
is a value >1
size
is the size of the type (in this case float
- 4
)
char *a = (char *)base;
char *temp = (char *)a + size * (i/2);
printf("%d: %d = ", i, temp);
memcpy(a + size * i , temp , size);
printf("%d\n", a + size * i);
This is the output:
2: 136724 = 136728
3: 136724 = 136732 4: 136728 = 136736 6: 136732 = 136744 7: 13673开发者_如何学C2 = 136748 8: 136736 = 136752If a
was a void*
, the compiler wouldn't allow you to write a + size*i
(you can't do pointer arithmetic with incomplete types). Probably the type isn't what you think it is.
But why do you think there's a problem? The left-hand column advances half as fast as the right-hand column, and this is expected because you are dividing by 2.
You do realize that you're printing addresses, and not the values being copied, right?
char *a = (char *)base;
char *temp = (char *)a + size * (i/2);
printf("%d: %f = ", i, *(float *)temp);
memcpy(a + size * i , temp , size);
printf("%f\n", *(float *)(a + size * i));
The changes I have made are to dereference the pointers correctly (and casting them to the correct type) and to change %d to %f as you specified that base is an array of floats. %d is for ints and %f is for floats.
The reason your code did not work is that you were printing out the addresses and not the values.
Would you please tell us what you're trying to accomplish? Seems like a homework problem, right?
The C language allows you to cast any pointer to a void*, and then cast it back to the original pointer type, without losing any information. Anything else you do with a void pointer is a bad idea, although some library functions (such as memcpy) still have void* for historical reasons. That's also why you don't need an explicit cast to go from any pointer type to a void*.
You cannot look at what the void* points to, until you cast it back to the correct pointer type. And be careful when you do!
#include <stdio.h>
#include <memory.h>
/* It's a bad idea to pass Base as a void pointer,
but that's what you said you have. */
void silly_function(void*base, int i, int size) {
/* Using a char* that points to float, is an even worse idea!
char *a = (char *)base;
char *temp = (char *)a + size * (i/2);
printf("%d: %d = ", i, temp);
memcpy(a + size * i , temp , size);
printf("%d\n", a + size * i);
**/
/** Probably ought to have a big SWITCH statement here, based
on the data type. sizeof() isn't a good way to do this...
On many computers, sizeof(float)==sizeof(long), but that
doesn't mean that a float* is the same as a long* !!!
For now, I'm going to assume (as you did) that base points
to an array of float. */
/* I think you're trying to copy the first half of the array
into the second half of the array! But that's easy. */
float*firsthalf = (float*)base;
float*secondhalf = firsthalf + (i/2);
/* Show some starting values. */
printf("Before: %x --> %f, %x --> %f\n",
firsthalf, *firsthalf, secondhalf, *secondhalf);
/* Now do the copy */
memcpy(secondhalf, firsthalf, (i/2)*(sizeof(float)));
/* Now prove that it's been copied? */
printf("After: %x --> %f, %x --> %f\n",
firsthalf, *firsthalf, secondhalf, *secondhalf);
}
int main() {
/* This drives the test */
float ary[10] = {
1.1f, 2.2f, 3.3f, 4.4f, 5.5f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
silly_function(ary, 10, sizeof(ary[0]));
return 0;
}
On my system, the output is
Before: 12ff38 --> 1.100000, 12ff4c --> 0.000000
After: 12ff38 --> 1.100000, 12ff4c --> 1.100000
I hope this helps.
精彩评论