在C语言中声明含几何图形的交集类型:如何避免频繁malloc?
无需动态分配内存实现几何图形交集链表
我已经声明了若干几何图形类型,示例如下:
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; // 其他几何图形类型...
现在我希望声明一个交集类型,其中包含两个double值和一个几何图形实例,随后将所有交集存储在链式链表中:
// 不知道该给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;
我可以用void* geometric_figure,但希望尽可能避免使用malloc。请问有没有便捷方法可以实现需求且无需为几何图形分配内存?
解决方案
方法1:共用体(Union)+ 类型标签
在交集结构体中加入枚举标签标识图形类型,用共用体直接存储不同几何图形的实例。这种方式无需动态分配,直接把图形数据嵌入交集结构体,缺点是共用体会占用所有图形类型中最大的内存空间。
// 定义图形类型枚举 typedef enum { FIGURE_SPHERE, FIGURE_CYLINDER, FIGURE_TRIANGLE, // 补充其他图形类型 } t_figure_type; typedef struct s_intersection{ double t1; double t2; t_figure_type type; // 标记当前存储的图形类型 union { t_sphere sphere; t_cylinder cylinder; t_triangle triangle; // 补充其他图形类型 } geometric_figure; } t_intersection;
使用示例:
t_intersection hit; hit.t1 = 1.0; hit.t2 = 3.0; hit.type = FIGURE_SPHERE; hit.geometric_figure.sphere.origin = (t_tuple){0,0,0,1}; hit.geometric_figure.sphere.radius = 5.0;
方法2:存储指向原图形的指针
如果几何图形本身是全局变量、栈上变量,或者生命周期长于交集链表的变量,直接存储指针即可,完全不需要动态分配。这种方式内存开销最小,只需保证原图形在交集链表使用期间不会被销毁。
// 同样需要类型标签区分指针指向的图形 typedef enum { FIGURE_SPHERE, FIGURE_CYLINDER, FIGURE_TRIANGLE, // 补充其他图形类型 } t_figure_type; typedef struct s_intersection{ double t1; double t2; t_figure_type type; void* geometric_figure; // 指向已存在的图形实例 } t_intersection;
使用示例:
// 假设sphere是已存在的栈变量或全局变量 t_sphere sphere = {{0,0,0,1}, 5.0}; t_intersection hit; hit.t1 = 1.0; hit.t2 = 3.0; hit.type = FIGURE_SPHERE; hit.geometric_figure = &sphere;
方法3:最大尺寸结构体占位
如果不想用共用体,先计算所有几何图形类型中尺寸最大的那个,用它作为geometric_figure的类型,配合类型标签识别实际存储的图形。原理和共用体类似,只是写法不同。
比如假设t_cylinder是尺寸最大的图形:
typedef enum { FIGURE_SPHERE, FIGURE_CYLINDER, FIGURE_TRIANGLE, // 补充其他图形类型 } t_figure_type; typedef struct s_intersection{ double t1; double t2; t_figure_type type; t_cylinder geometric_figure; // 用最大尺寸结构体占位 } t_intersection;
使用示例:
t_intersection hit; hit.t1 = 1.0; hit.t2 = 3.0; hit.type = FIGURE_SPHERE; // 将sphere数据拷贝到占位的内存中 *(t_sphere*)&hit.geometric_figure = sphere; // 读取时判断类型再强制转换 if (hit.type == FIGURE_SPHERE) { t_sphere* s = (t_sphere*)&hit.geometric_figure; // 使用s->origin等字段 }
内容的提问来源于stack exchange,提问作者BobDeTunis
相关产品推荐
相关产品推荐

