Первый вопрос, кто является владельцем структур, которые вы собираетесь освободить.
Возможно, API возвращает указатель на свою внутреннюю структуру, которую вы не должны освобождать (поскольку, например, он может быть общим).
Возможно, ваш код отвечает за освобождение самой структуры, а не других структур, на которые указывает ваша структура. Таким образом, вам нужно просто освободить возвращенную структуру и забыть об этом.
Однако, возможно, вы несете ответственность за освобождение всего дерева объектов, начиная с возвращенной структуры. В этом случае следует ожидать, что в API есть какая-то функция, которая должным образом освобождает структуру от ее потомков. Если нет (что, скорее всего, не так), вы должны освободить все ресурсы, на которые ссылается ваша структура, рекурсивно.
Вам следует просмотреть документацию APi, чтобы выяснить, какие из трех случаев являются вашими.
Обновление:
Явно для вашего случая (вся структура должна быть удалена вручную), я бы использовал что-то вроде этого:
void free_mem_stat(struct mem_stat* p)
{
if (!p) return;
free(p->mem_name);
free(p);
}
void free_dev_stat(struct dev_stat* p)
{
// first, clean up the leaves
for(struct dev_stat* curr = p; curr; curr = curr->next_dev)
{
free(curr->dev_name);
free_mem_stat(curr->mem_info);
}
// than, clean up the linked list
for(struct dev_stat* curr = p; curr; /**/)
{
struct dev_stat* next = curr->next_dev;
free(curr);
curr = next;
}
}
int callApi(int ip)
{
int ret_val;
struct dev_stat* output;
ret_val = API(ip, &output);
free_dev_stat(output);
return ret_val;
}
Обратите внимание, что такая функция, как free_dev_stat
, должна предоставляться самим API, если разработчики API действительно намерены позволить пользователям освободить свои структуры.