How to put a literal network into dynamic memory using memcpy? Bug xcode?

advertisements

I want to put a literal array into a dynamic memory.

double *rgb = (double*)malloc(3 * sizeof(double));
memcpy(rgb, (double []){1,2,3}, sizeof(rgb));

but I get the error: Too many arguments provided to function-like macro invocation.

But if I do this:

double *rgb = (double*)malloc(3 * sizeof(double));
memcpy(rgb, (double []){1}, sizeof(rgb));

The compiler yields no errors? Why?

Is Objective-c bugged ... or am I missing something?


Too many arguments provided to function-like macro invocation.

memcpy() is apparently implemented by your compiler/stdlib as a preprocessor function macro (i.e. a #define somewhere in your lib's header files). So this line

memcpy(rgb, (double []){1,2,3}, sizeof(rgb));

is reading the commas inside and considering them as argument separators (remember, the preprocessor knows nothing about the C code except what a token is). To the preprocessor, you have 5 arguments rgb, (double []){1, 2, 3}, and sizeof(rgb). It expects 3 arguments.


With regard to how to initialise dynamic memory, this works with gcc in c99 standard mode:

double *rgb = (double*)malloc(3 * sizeof(double));
memcpy(rgb, (double []){1,2,3}, 3 * sizeof(double));

... so apparently gcc's stdlib does not use a macro for memcpy.

Also note that sizeof(rgb) = 4 or 8, because rgb is a pointer: sizeof a pointer is the size of a memory address, not of the length of the array. Thus, I used 3 * sizeof(double) in the memcpy call.

In a more complex program, you would have to pass the length of the array around along with a pointer to the array, in order for that information to be available to code that manipulates the array.

For your particular compiler, this may be a solution (although if this isn't optimised away, it's less efficient—presumably you wouldn't be hard-coding initialisation data that's large enough for this to matter?):

double rgb_initial[] = {1, 2, 3};
double * rgb = (double *) malloc(3 * sizeof(double));
memcpy(rgb, rgb_initial, 3 * sizeof(double));