【问题标题】:Smart Pointer Implementation in C [duplicate]C中的智能指针实现[重复]
【发布时间】:2011-04-06 22:50:02
【问题描述】:

可能重复:
Smart pointers/safe memory management for C?

我有一个嵌入式应用程序,我在动态内存中分配一个对象并将其传递给其他模块。

我想创建一个指向该对象的智能指针。 C++中有很多使用和实现智能指针的例子。

我正在寻找智能指针的仅 C 语言实现。

谢谢。

【问题讨论】:

  • 但是...C 中没有构造函数/析构函数!
  • 显然,构造函数和析构函数是智能指针的核心。
  • 是的,没有它们,“智能指针”会变成愚蠢的“引用计数器”。
  • 事实上,可以在 C 中使用析构函数和智能指针(针对 gcc 和 clang 进行了测试),请参阅我的 response 关于另一个问题。

标签: c pointers smart-pointers c99


【解决方案1】:

是的,我认为这是不可能的(或者至少没有那么有用),因为 @KennyTM 所说的。智能指针是可能的,因为构造函数和析构函数被自动调用。否则,您必须自己调用 reference() 和 unreference()。还有用吗?

另外,请参阅之前非常相关的 SO 问题:Smart pointers/safe memory management for C?

【讨论】:

  • 感谢您的回答。该对象是闪存的句柄。我将使用另一种策略。
【解决方案2】:

您可以构造一个完全封装的“不透明”类型,并按照您在 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,但当然编译器不会为您强制执行。

所以,这很麻烦,你应该仔细考虑你可能会得到什么。

【讨论】:

  • 我看不出这与智能指针有什么关系...
  • @R..:嗯,这种机制允许您支持引用计数指针。它保留了一个很大的弱点,即您必须在它们超出范围之前显式删除它们。这不像 OO 语言支持的那样“聪明”,但它确实集中了引用计数代码,并使内存管理成为严格的本地事务......只要你保持纪律永不破坏封装。
  • 值得注意的是,诸如 PalmOS 之类的某些系统的操作与您描述的非常相似,尽管它们要求在使用指针取消引用对象时调用函数。这种方法的一个优点是对象可以透明地重新定位 - 避免碎片 - 任何时候不存在任何指向它们的直接指针(至少没有任何人会实际使用)。
  • @supercat:经典 Mac OS(直到系统 7.6)完全出于内存管理目的(这些系统上没有适当的虚拟内存)做了类似的事情。
  • @dmckee:确实,PalmOS 句柄可能在某种程度上模仿了 MacOS 句柄,但也有一些不同之处。最大的不同是 MacOS 明确允许代码说“void *myPtr = *myHandle;”作为取消引用句柄的一种方法,前提是人们期望某些系统调用可能导致任何或所有句柄分配的对象移动;在 PalmOS 中,访问句柄的唯一方法是使用 pin 函数。
【解决方案3】:

我倾向于认为智能指针为您做(至少)两件事:

  • 自动管理内存/对象的生命周期(资源分配)
  • 自动管理对象的所有权(复制语义等)

第二个方面可以近似通过实现一个不允许人们直接复制/分配指针的强大 API。

但第一项是 C++ 及其对构造函数/析构函数(RAII 的核心)的语言支持真正大放异彩的地方。事实上,构造函数和析构函数通过由编译器自动插入的代码在正确的位置被调用,这使得魔法起作用。如果没有对 CTOR 和 DTOR 的内置语言支持,您将只是近似效果,或者在必要时依赖用户“做正确的事情”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-30
    • 2014-03-10
    • 1970-01-01
    • 2011-08-14
    • 2011-06-28
    • 1970-01-01
    相关资源
    最近更新 更多