Всех приветствую!
Может кому-нибудь мой вопрос покажется надуманным, но все равно напишу.
Есть (в данном примере игрушечный) код
KIT* kit=NULL;
// создаем kit
kit = kit_create("Abracadabra", 5);
// пользуемся kit
// ...
kit_print(stdout, kit);
// ...
// освобождаем kit
kit_free(kit);
// ...
// забыли, что уже освободили kit и делаем распечатку
kit_print(stdout, kit);
//Segmentation fault
Segmentation fault
Т.к. после
#define SAFE_FREE(object) if(object!=NULL) {free(object); (object)=NULL;}
void kit_free(KIT *kit)
{
SAFE_FREE(kit->name);
SAFE_FREE(kit->data);
SAFE_FREE(kit);
}
указатель на kit не будет NULL на вызывающей стороне. И даже если сделать проверку в kit_print
if (kit != NULL && kit->data != NULL)
{
// печатаем kit
}
else
printf("Извините, но kit=NULL");
все равно в kit_print придет ненулевой указатель.
Варианты решения:
kit_free(kit);
kit=NULL;
Недостаток: лишняя строка которую можно забыть написать, и вообще хотелось бы чтобы все делалось в kit_free
Сделать
KIT* kit_free(KIT *kit)
{
SAFE_FREE(kit->name);
SAFE_FREE(kit->data);
SAFE_FREE(kit);
return kit; // уже ставший NULL
}
и вызывать
kit = kit_free(kit);
Выглядит неплохо.
А теперь вопрос:
Имеются ли у кого-нибудь более изящные решения или возможен иной принципиально подход к освобождению памяти в pure C ?