In a project I'm working on, I find myself creating a lot of small, hand-written arrays of structs that need to be stored in dynamically allocated memory (mostly for testing with small datasets before importing from a file). There's a really nice syntax to initialize a static array of structs, as vec2
below, but I've been using the solution vec3
below that uses memcpy
.
vec4
shows sort of what I'd like to be able to do, but obviously it doesn't quite work. Even though the anonymous array *((struct vec2d[]) { {1, 2}, {3, 4}, {5, 6} })
contains three strut vec2d
s, when it (and the LHS) are dereferenced, they become (struct vec2d)
, so only the first struct vec2d
gets assigned to the memory allocated at vec4
.
Is there some way for me to accomplish this purely as an assignment, without using memcpy?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct vec2d
{
double x,y;
};
//void print_vec2d(char *, struct vec2d *);
void print_vec2ds(char *label, size_t count, struct vec2d *vec)
{
for (size_t i = 0; i < count; i++)
{
printf("%s (%li of %li): (%f, %f)\n", label, i + 1, count, (vec[i]).x, (vec[i]).y);
}
printf("\n");
}
int
main(int c, char **a)
{
// nice and concise syntax
struct vec2d vec2[3] =
{
{12, 34},
{56, 78},
{90, 112}
};
print_vec2ds("vec2", 3, vec2);
// a little bulky to have to wrap it all in a call to memcpy
struct vec2d *vec3 = calloc(3, sizeof(struct vec2d));
memcpy(vec3, (struct vec2d[])
{
{1, 2},
{3, 4},
{5, 6}
}, 3*sizeof(struct vec2d));
print_vec2ds("vec3", 3, vec3);
// this doesn't (and shouldn't) work, but I like the syntax :)
struct vec2d *vec4 = calloc(3, sizeof(struct vec2d));
*vec4 = *((struct vec2d[])
{
{1, 2},
{3, 4},
{5, 6}
});
print_vec2ds("vec4", 3, vec4);
}
program output, showing how last assignment doesn't work:
vec2 (1 of 3): (12.000000, 34.000000)
vec2 (2 of 3): (56.000000, 78.000000)
vec2 (3 of 3): (90.000000, 112.000000)
vec3 (1 of 3): (1.000000, 2.000000)
vec3 (2 of 3): (3.000000, 4.000000)
vec3 (3 of 3): (5.000000, 6.000000)
vec4 (1 of 3): (1.000000, 2.000000)
vec4 (2 of 3): (0.000000, 0.000000)
vec4 (3 of 3): (0.000000, 0.000000)
Incidentally, I discovered that it's possible to cast the LHS and RHS of the assignment into the pointer type of a struct which holds the amount of data I want to assign:
struct bad {double a,b,c,d,e,f};
struct vec2d *vec5 = calloc(3, sizeof(struct vec2d));
*((struct bad*) vec5) = *((struct bad*) ((struct vec2d[])
{
{1, 2},
{3, 4},
{5, 6}
}));
print_vec2ds("vec5", 3, vec5);
which "works", but it requires a struct of the precise length to be defined, which isn't really a solution…