You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 16:35:21