Реализация умного указателя на C

Возможный дубликат:
Умные указатели / безопасная память управление для C?

У меня есть встроенное приложение, в котором я выделяю объект в динамической памяти и передаю его другим модулям.

Я хочу создать умный указатель на этот объект. В C ++ есть много примеров использования и реализации интеллектуальных указателей.

Я ищу только реализацию умного указателя на языке C.

Спасибо.


person Thomas Matthews    schedule 01.09.2010    source источник
comment
Но ... в C нет конструкторов / деструкторов!   -  person kennytm    schedule 01.09.2010
comment
Судя по всему, в основе умного указателя лежат конструкторы и деструкторы.   -  person Thomas Matthews    schedule 01.09.2010
comment
Да, без них умные указатели превращаются в тупые счетчики ссылок.   -  person Scott Stafford    schedule 01.09.2010
comment
Фактически, возможно иметь деструкторы и интеллектуальные указатели в C (протестированы для gcc и clang), см. Мой ответ по другому вопросу.   -  person Snaipe    schedule 10.01.2015


Ответы (3)


Да, я думаю, что это невозможно (или, по крайней мере, не так полезно) из-за того, что говорит @KennyTM. Умные указатели возможны благодаря автоматическому вызову конструкторов и деструкторов. В противном случае вам придется самостоятельно вызывать reference () и unreference (). Все еще полезно?

Также см. Этот предыдущий, очень связанный вопрос SO: Умные указатели / безопасное управление памятью для C?

person Scott Stafford    schedule 01.09.2010
comment
Спасибо за ответ. Объект представляет собой дескриптор флэш-памяти. Я воспользуюсь другой стратегией. - person Thomas Matthews; 01.09.2010

Вы можете создать «непрозрачный» тип, который полностью инкапсулирован, и делать то, что вы хотите, во многом так же, как в C ++.

Нравится.

smartpointer.h:

typedef struct sp smartpointer;

smartpointer new(void *content, size_t s);
int          delete(smartpointer p)
void*        dereference(smartpointer p);
/* ... */

smartpointer.c

/* contains the definition of "struct sp" and the implementation of the 
   the functions */

а затем пообещайте себе никогда и никогда не обращаться к данным, кроме как с помощью dereference, но, конечно, компилятор не будет обеспечивать это за вас.

Таким образом, все это доставляет массу хлопот, и вам следует очень хорошо подумать о том, что вы можете получить.

person dmckee --- ex-moderator kitten    schedule 01.09.2010
comment
Я не понимаю, какое отношение это имеет к умным указателям ... - person R.. GitHub STOP HELPING ICE; 01.09.2010
comment
@R ..: Этот механизм позволяет поддерживать указатели с подсчетом ссылок. Он сохраняет большую слабость, заключающуюся в том, что вы должны явно удалить их, прежде чем они выйдут из области видимости. Это не так разумно, как поддержка языка OO, но оно действительно централизует код подсчета ссылок и делает управление памятью строго локальным делом ... до тех пор, пока вы сохраняете дисциплину, чтобы никогда не нарушать инкапсуляцию. - person dmckee --- ex-moderator kitten; 01.09.2010
comment
Стоит отметить, что некоторые системы, такие как PalmOS, делают вещи примерно так же, как вы описываете, хотя они требуют, чтобы функция вызывалась, когда она выполняется с использованием указателя для разыменования объекта. Одним из преимуществ этого подхода является то, что объекты можно прозрачно перемещать - избегая фрагментации - в любое время, когда на них не существует прямых указателей (по крайней мере, таких, которые кто-либо когда-либо действительно будет использовать). - person supercat; 29.04.2012
comment
@supercat: Классическая Mac OS (до системы 7.6) сделала что-то подобное полностью для целей управления памятью (в этих системах нет надлежащей виртуальной памяти). - person dmckee --- ex-moderator kitten; 29.04.2012
comment
@dmckee: Действительно, дескрипторы PalmOS, вероятно, были смоделированы несколько после дескрипторов MacOS, но были некоторые отличия. Самая большая разница в том, что MacOS явно разрешает коду сказать void * myPtr = * myHandle; как средство разыменования дескриптора, при условии, что ожидается, что определенные системные вызовы могут вызвать перемещение любого или всех выделенных дескриптором объектов; в PalmOS единственный способ получить доступ к дескриптору - это закрепить его. - person supercat; 29.04.2012

Я склонен думать, что умные указатели делают (по крайней мере) две вещи для вас:

  • автоматическое управление временем жизни (выделением ресурсов) памяти / объекта
  • автоматическое управление владением объекта (семантика копирования и т. д.)

Второй аспект можно приблизить путем реализации сильного API, который не позволяет людям напрямую копировать / назначать указатели.

Но в первом пункте действительно сияют C ++ и его языковая поддержка конструкторов / деструкторов (сердце RAII). Именно тот факт, что конструкторы и деструкторы вызываются посредством кода, который автоматически вставляется компилятором в нужные места, заставляет волшебство работать. Без встроенной языковой поддержки CTOR и DTOR вы просто приблизительно оцените эффект или положитесь на пользователя, который «поступит правильно», когда это необходимо.

person Dan    schedule 04.09.2010