Bob*_*nis 2 c unions flexible-array-member
这是我声明的类型:(
我也t_sphere声明了)t_cylindert_triangle
typedef struct s_intersection{
double t1;
double t2;
int id;
union {
t_sphere sph;
t_cylinder cyl;
t_triangle tri;
} u[];
} t_intersection;
Run Code Online (Sandbox Code Playgroud)
要引用结构体中的联合变量,我必须提前知道它是什么类型。这是可能的,这要归功于我的结构中声明的 id int,但是用我想到的方法来实现它是非常繁重的。
这是我编写的用于分配 t_intersection 变量的函数:
t_intersection *intersection(unsigned int geometric_figure_id, void *figure)
{
t_intersection *p;
if (geometric_figure_id == SPHERE_ID)
p = malloc(sizeof(*p) + sizeof (p->u[0].sp));
else if (geometric_figure_id == CYLINDER_ID)
p = malloc(sizeof(*p) + sizeof (p->u[0].cy));
else if (geometric_figure_id == TRIANGLE_ID)
p = malloc(sizeof(*p) + sizeof (p->u[0].tr));
if (p == NULL)
return (NULL);
memset(&p, 0, sizeof(p));
p->id = geometric_figure_id:
if (geometric_figure_id == SPHERE_ID)
p->u[0].sp = *(t_sphere *)figure;
else if (geometric_figure_id == CYLINDER_ID)
p->u[0].cy = *(t_cylinder *)figure;
else if (geometric_figure_id == TRIANGLE_ID)
p->u[0].tr = *(t_triangle *)figure;
return (p);
}
Run Code Online (Sandbox Code Playgroud)
有更好的方法来实现这一目标吗?
编辑:我添加了我忘记的 malloc + 分配了 id...
您需要始终为整个联盟分配空间,而不仅仅是一个成员。此外,您还可以用来calloc分配零初始化的内存。
所以你可以替换这个:
if (geometric_figure_id == SPHERE_ID)
p = malloc(sizeof(*p) + sizeof (p->u[0].sp));
else if (geometric_figure_id == CYLINDER_ID)
p = malloc(sizeof(*p) + sizeof (p->u[0].cy));
else if (geometric_figure_id == TRIANGLE_ID)
p = malloc(sizeof(*p) + sizeof (p->u[0].tr));
if (p == NULL)
return (NULL);
memset(&p, 0, sizeof(p));
Run Code Online (Sandbox Code Playgroud)
有了这个:
p = calloc(1, sizeof(*p) + sizeof (p->u[0]));
if (p == NULL)
return (NULL);
Run Code Online (Sandbox Code Playgroud)
为了进一步简化,由于您每次只创建联合的一个实例,因此不需要灵活的数组成员。只需像这样声明您的结构:
typedef struct s_intersection{
double t1;
double t2;
int id;
union {
t_sphere sph;
t_cylinder cyl;
t_triangle tri;
};
} t_intersection;
Run Code Online (Sandbox Code Playgroud)
并创建一个像这样的实例:
t_intersection *intersection(unsigned int geometric_figure_id, void *figure)
{
t_intersection *p;
p = calloc(1, sizeof(*p));
if (p == NULL)
return (NULL);
p->id = geometric_figure_id:
if (geometric_figure_id == SPHERE_ID)
p->sp = *(t_sphere *)figure;
else if (geometric_figure_id == CYLINDER_ID)
p->cy = *(t_cylinder *)figure;
else if (geometric_figure_id == TRIANGLE_ID)
p->tr = *(t_triangle *)figure;
return (p);
}
Run Code Online (Sandbox Code Playgroud)