Reputation: 3737
Currently, I have a struct camera
that holds two fixed size variables f
and p
struct point {
double x, y, z;
};
struct camera {
struct point f[5], p[5];
};
Making f
and p
flexible results in error. I followed the instructions given in this SO question and decided to go for non-struct variables and pass them to functions instead which resulted in long function call syntax and messy structure.
My question, although subjective, is: what is the best approach to have two flexible arrays that can be accessed via one point (similar to struct, etc.)?
Upvotes: 1
Views: 716
Reputation: 726489
Here is an approach that mimics two flexible arrays of identical type: make one flexible array that holds both arrays, and add a pointer into the array at the position where the second flexible array starts:
struct camera {
struct point *p;
struct point f[];
};
When you allocate camera
, provision the space for both arrays, and add it to the "raw" sizeof(struct camera)
. Let's say your first array has n
elements, and the second one has m
. Then you initialize your camera
as follows:
struct camera *c = malloc(sizeof(*c)+(n+m)*sizeof(struct point));
c->p = &(c->f[n]); // Point "p" to the beginning of the second array
for (int i = 0 ; i != n ; i++) {
c->f[i] = ... // Init points in f
}
for (int i = 0 ; i != m ; i++) {
c->p[i] = ... // Init points in p
}
Upvotes: 1
Reputation: 153348
A non flexible array approach follows that, IMO, addresses OP's higher level problem of "long function call syntax and messy structure" with a cleaner pair of struct point
pointers.
struct camera {
size_t size; // add size member
struct point *f;
struct point *p;
};
bool camera_initialize(struct camera *cam, size_t size) {
// Use 1 or 2 allocations
cam->f = malloc(sizeof *(cam->f) * 2 * size);
if (cam->f) {
cam->p = cam->f + size;
cam->size = size;
return false; // success
} else {
cam->p = cam->f = NULL;
cam->size = 0;
return size > 0; // fail if size was not 0
}
}
void camera_uninitialize(struct camera *cam) {
free(cam->f);
cam->p = cam->f = NULL;
cam->size = 0;
}
Sample usage
int main() {
size_t n = foo();
struct camera cam;
if (camera_initialize(&cam, n)) return EXIT_FAILURE;
bar(cam.f, cam.n);
bar(cam.p, cam.n);
camera_uninitialize(&cam);
}
Upvotes: 2
Reputation: 170055
By definition you can't have two flexible array members. A flexible array member must be the last in the structure, there can only be a single "last" element.
But I sense you apparently need to pair up f
and p
, so why not aggregate them? Then you can have a flexible array member of those pairs:
#include <stdio.h>
#include <stdlib.h>
struct point {
double x, y, z;
};
struct camera {
char dummy;
struct {
struct point f, p;
} pairs[];
};
int main(void) {
struct camera *c = malloc(sizeof(*c) + sizeof(c->pairs[0])*5);
return 0;
}
Note the use of C99's support for flexible array members.
Upvotes: 2