Нет, нет пути.
Однако вы можете использовать небольшую дисциплину кода следующим образом:
Всегда всегда всегда выделение защиты с помощью malloc:
void * vp;
if((vp = malloc(SIZE))==NULL){
/* do something dreadful here to respond to the out of mem */
exit(-1);
}
После освобождения указателя установите его на 0
free(vp); vp = (void*)0;
/* I like to put them on one line and think of them as one peration */
В любом месте, где у вас будет соблазн использовать вашу функцию «свободен», просто скажите
if(vp == NULL)[
/* it's been freed already */
}
Обновление
@ Иисус в комментариях говорит:
Я не могу порекомендовать это, потому что, как только вы закончите с этим
память указатель должен немедленно выйти из области видимости (или, по крайней мере, в
конец функции, которая его освобождает) эти висячие указатели
существование просто не подходит мне.
Обычно это хорошая практика, когда это возможно; проблема в том, что в реальной жизни на С это часто невозможно. В качестве примера рассмотрим текстовый редактор, содержащий двусвязный список строк. Список действительно прост:
struct line {
struct line * prev;
struct line * next;
char * contents;
}
Я определяю guarded_malloc
функцию, которая выделяет память
void * guarded_malloc(size_t sz){
return (malloc(sz)) ? : exit(-1); /* cute, eh? */
}
и создать список узлов с newLine()
struct line * newLine(){
struct line * lp;
lp = (struct line *) guarded_malloc(sizeof(struct line));
lp->prev = lp->next = lp-contents = NULL ;
return lp;
}
Я добавляю текст в строку s
в мою строку
lp->contents = guarded_malloc(strlen(s)+1);
strcpy(lp->contents,s);
и не говорите, что я должен использовать формы ограниченной длины, это всего лишь пример.
Теперь, как я могу реализовать удаление содержимого line
, которое я создал, когда char * contents
выходит из области видимости после освобождения?