Вы не можете делать интеллектуальные указатели в C, потому что он не обеспечивает необходимый синтаксис, но вы можете избежать утечек с практикой. Напишите код выпуска ресурса сразу после его выделения. Поэтому всякий раз, когда вы пишете malloc
, вы должны написать соответствующий free
непосредственно в разделе очистки.
В CI увидеть «GOTO очистки» модель много:
int foo()
{
int *resource = malloc(1000);
int retVal = 0;
//...
if (time_to_exit())
{
retVal = 123;
goto cleanup;
}
cleanup:
free(resource);
return retVal;
}
В C мы также используем много контекстов, которые выделяют вещество, такое же правило может быть применено для этого тоже:
int initializeStuff(Stuff *stuff)
{
stuff->resource = malloc(sizeof(Resource));
if (!stuff->resource)
{
return -1; ///< Fail.
}
return 0; ///< Success.
}
void cleanupStuff(Stuff *stuff)
{
free(stuff->resource);
}
Это аналогично конструкторам объектов и деструкторам. Пока вы не отдаете выделенные ресурсы другим объектам, они не будут течь, а указатели не будут болтаться.
Нетрудно написать пользовательский распределитель, который отслеживает распределения и записывает утечки блоков atexit
.
Если вам нужно указать указатели на выделенные ресурсы, вы можете создать для него контексты-оболочки, и каждый объект будет обладать контекстом-оболочкой вместо ресурса. Эти оболочки обмениваются ресурсом и объектом-счетчиком, который отслеживает использование и освобождает объекты, когда никто его не использует. Вот как работает C++ 11's shared_ptr
и weak_ptr
. Здесь написано более подробно: How does weak_ptr work?
Как это работает? Как он может отслеживать назначения указателя? – Calmarius
@Calmarius Существуют различные способы их работы. См .: http://en.wikipedia.org/wiki/Garbage_collection_(computer_science) –
Я вижу. Я спросил о GC, с которой вы связались. Он утверждает, что он работает с немодифицированными программами C, заменяя только malloc и realloc. Но как он находит указатели, указывающие на выделенный блок? Они могут быть скопированы в программе. – Calmarius