2

I declared a few geometric figures types such as:

typedef struct s_sphere{ t_tuple origin; double radius; } t_sphere; typedef struct s_cylinder{ t_tuple origin; double height; double radius; } t_cylinder; typedef struct s_triangle{ t_tuple A; t_tuple B; t_tuple C; } t_triangle; etc... 

Now, I would like to declare an intersection type which will contain two doubles and a geometric figure. I will then store all my intersections in a chained list:

// I do not know what type to give to geometric_figure typedef struct s_intersection{ double t1; double t2; // what_type geometric_figure; } t_intersection; typedef struct s_intersection_list{ t_intersection intersection; struct s_intersection_list *next; } t_intersection_list; 

I could use void* geometric_figure but I would like to avoid the most mallocs possible.
Is there a handy way of getting where I want without allocating geometric_object ?

1
  • 5
    You may use a union. Commented Feb 4, 2023 at 12:57

1 Answer 1

4

type which will contain two doubles and a geometric figure.

Consider union with an identifier.

typedef struct s_intersection{ double t1; double t2; int id; // some id to know what type follows union { t_sphere sph; t_cylinder cyl; t_triangle tri; } u; } t_intersection; 

If t_intersection is to be allocated, consider a flexible member array to right size the allocation.

typedef struct s_intersection{ double t1; double t2; int id; // some id to know what type follows union { t_sphere sph; t_cylinder cyl; t_triangle tri; } u[]; // FAM } t_intersection; 

Example: allocate a triangle.

t_intersection *p = malloc(sizeof *p + sizeof p->u[0].tri); 
Sign up to request clarification or add additional context in comments.

6 Comments

The FMA part is very interesting. To be sure I get it right, its purpose is to allocate the exact right size to a t_intersection variable ? Like if I chose to not use FAM, a t_intersection variable would always have a size of ``` 2*doubles + int + max_size(union types) = 2*8 + 4 + 3*4*8 = 116 bytes``` (because t_tuples contain 4 doubles so max_size(union types) = sizeof (t_triangle)). Whereas if I use an FAM, it will have a size of ``` 2*doubles + int + sizeof(chosen figure) = 2*8 + 4 + chosen types = 20 + sizeof (chosen figure) bytes```. Am I right ?
@BobDeTunis Yes, almost. The size of a struct includes potential padding in both cases. With a FAM, sizeof *p includes all prior members and padding up to the .u member.
In the link you provided, it is written "The sizeof operator on such a struct gives the size of the structure as if the flexible array member were empty. This may include padding added to accommodate the flexible member; the compiler is also free to re-use such padding as part of the array itself." So won't the struct padding be re-used by the FMA making my calculations correct ?
@BobDeTunis Say the first member of a new figure was complex long double with an alignment of 32 requirement. Then the expected size of t_intersection (no FAM) is 8 + 8 + 4 + (32-(8+8+4)) + max_size(figures). The expected size of t_intersection (with FAM) is 8 + 8 + 4 + (32-(8+8+4)).
@BobDeTunis "the only con of the FAM version to require allocations " --> With a FAM, allocations are not required if the .u member is not used - just use t_intersection p;. FMA requires C99 or later and programmers/tools not stuck in C89. Perhaps other disadvantages.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.