В целом, важно, чтобы библиотека документировала «контракт», который она заключает с приложениями, которые используют ее сервис. Автор библиотеки документирует все выделения, сделанные библиотекой, и то, что должно быть освобождено приложением. Как и любой контракт, хорошо, когда он прост и последовательн.
В этом конкретном случае, я полагаю, библиотека также должна предлагать:
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()
должны объяснить, что он может быть вызван только один раз, и что в этом случае приложение берет на себя ответственность за освобождение массива.
UPDATE:
В ответ на ваш комментарий ниже: Прежде всего, обратите внимание, что я упростил проблему, предполагая (по крайней мере) следующее: на d
ссылается либо одна bs
структура, либо приложение. Приложение и библиотека «передают» одну ссылку на массив от одного к другому. Например, если вам нужен один и тот же массив d
в большем количестве bs
структур, то моего подхода недостаточно.
Флаг, который вы предлагаете в комментарии, может помочь, но это не стандартная практика, FWIK. В этом случае я бы предложил реализовать простой подсчет ссылок . Если d
- это ресурс, которым нужно делиться, сделайте его «объектом»:
typedef struct {
double **d;
int ref;
} d_t;
Инициализировать ref
с помощью 1. В new_bs()
и во всех функциях, которые получают «копию» d
, увеличить счетчик ссылок. Когда структура bs
будет удалена или когда вам больше не понадобится d
в вашем приложении, уменьшите счетчик ссылок. Если он достигнет нуля, освободите его. В некотором смысле, это то, что языки высокого уровня делают для вас, и очень эффективно поддерживают управление ресурсами в здравом уме.
То есть массив не принадлежит никому, но тот, кто в нем нуждается последний, освобождает его.
Конечно, это требует больше работы и усложняет код, поэтому постарайтесь найти баланс. Он не нужен для каждой имеющейся у вас структуры, но только для тех, на которые нужно хранить несколько ссылок.