gpt4 book ai didi

c - 结构 : between a calling program and library (in c) 中的共享对象

转载 作者:太空宇宙 更新时间:2023-11-04 01:43:10 26 4
gpt4 key购买 nike

在一个单独的库中,我们有一个结构:

typedef struct bsmat{
int m;
int *n;
double **d;
} bs;

其中 **d 是指向 double 组的指针数组。

bs *new_bs(int n, double **d);

有两个用例:

(a) 主应用分配多个 double 矩阵并调用库构造结构。

b = new_bs(5, p)

(b) 或者,作为函数调用的结果,库可以生成一个对象:

bs *add(bs *a, bs *b);

在第二种情况下,库拥有 **d 并且可以在必要时释放它。在第一种情况下,应用程序已经分配了数组并且库可以读取/写入它。我不清楚谁应该释放什么以及何时释放?

允许主应用程序拥有结构成员是否有问题?这种方法有什么问题?有哪些选择?我们正在努力避免来回复制大量数组。

谢谢

TR

最佳答案

一般来说,图书馆记录它与使用其服务的应用程序签订的“契约(Contract)”很重要。库编写器记录了库所做的所有分配以及应用程序需要释放的内容。与任何契约(Contract)一样,简单且一致的契约(Contract)是好的。

在这种特殊情况下,我想图书馆还应该提供:

void free_bs(bs *b) 
{
if (b->d) {
/* free b->d here */
}
/* free rest of the structure */
}

释放结构。在这里释放 d 数组也是有意义的。应用程序具有指向所有 bs 结构的指针,并负责在不再需要时对它们调用 free_bs

例如,如果您想保留 d 以供将来使用,那么在完成库操作后,合约会稍微复杂一些。图书馆还可以提供:

double** bs_get_data(bs *b)
{
double **d = b->d;
b->d = NULL;
return b->d;
}

它返回指向 d 的指针,并将该字段留空,以便自由例程知道要跳过它。

bs_get_data() 的文档必须解释它只能被调用一次,并且在这种情况下应用程序负责释放数组。

更新:在回答您的以下评论时:首先,请注意我通过(至少)以下假设简化了问题:d 由单个 bs 引用结构或应用程序。应用程序和库将对数组的单个引用从一个传递到另一个。例如,如果您想要在多个 bs 结构中使用相同的 d 数组,那么我的方法是不够的。

您在评论中提出的标志可能会有所帮助,但不是标准做法,FWIK。在这种情况下,我建议实现一些简单的引用计数。如果 d 是需要共享的资源,将其设为“对象”:

 typedef struct {
double **d;
int ref;
} d_t;

用 1 初始化 ref。在 new_bs() 和所有接收 d 的“副本”的函数中,增加引用计数.当 bs 结构被删除时,或者当您在应用程序中不再需要 d 时,减少它的引用计数。如果它变为零,则释放它。在某种程度上,这就是高级语言为您所做的,并且在保持资源管理健全方面非常有效。

因此没有人拥有该数组,但最后需要它的人会释放它。

当然,这需要更多的工作并使代码复杂化,所以尽量平衡。并非您拥有的每个结构都需要它,但只有那些您需要保留多个引用的结构才需要。

关于c - 结构 : between a calling program and library (in c) 中的共享对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1236133/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com