LINUX.ORG.RU

Как гарантированно заNULLить указатель на уже освобожденный объект

 , , ,


0

4

Всех приветствую!

Может кому-нибудь мой вопрос покажется надуманным, но все равно напишу.

Есть (в данном примере игрушечный) код

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 ?