c++ - 在 C++11 中使用智能指针环绕旧的 C 结构并自动释放它们

标签 c++ c c++11 wordnet

我正在使用 Word-Net ,普林斯顿大学在九十年代开发的旧 C 库。 该库是用 C 编写的,仅显示 header ,但不显示其实际实现。

我使用的唯一结构是:

SynsetPtr

我调用的两个函数是:

findtheinfo_ds

traceptrs_ds

这两个函数都返回一个 SynsetPtr。

但是,当 SynsetPtr 表示意义列表时,我必须使用它来释放它

free_syns

然而,当 SynsetPtr 用于遍历链表(分层树)时,我必须使用释放它

free_synset

Documentation不太清楚何时调用哪个以及为什么调用。

这很快成为我的噩梦。我花了三天时间慢慢解决泄漏、双重释放、内存分配等问题。

所以我想知道,有没有一种方法可以环绕这些函数或实际结构,并让 C++ 管理内存?理想情况下,我希望在不再引用它们时释放它们,就像 std::shared_ptr 的情况一样。

这可能吗,知道 Synset_Ptr 没有析构函数,但必须调用 dealloc 函数吗?

或者,我能否环绕创建(分配)这些结构的两个函数,以某种方式记录对象,并在没有对它们的引用时销毁它们?

我非常感谢任何帮助!

编辑:

这是wn.h中SynsetPtr的准确声明

/* Structure for data file synset */
typedef struct ss {
    long hereiam;       /* current file position */
    int sstype;         /* type of ADJ synset */
    int fnum;           /* file number that synset comes from */
    char *pos;          /* part of speech */
    int wcount;         /* number of words in synset */
    char **words;       /* words in synset */
    int *lexid;         /* unique id in lexicographer file */
    int *wnsns;         /* sense number in wordnet */
    int whichword;      /* which word in synset we're looking for */
    int ptrcount;       /* number of pointers */
    int *ptrtyp;        /* pointer types */
    long *ptroff;       /* pointer offsets */
    int *ppos;          /* pointer part of speech */
    int *pto;           /* pointer 'to' fields */
    int *pfrm;          /* pointer 'from' fields */
    int fcount;         /* number of verb frames */
    int *frmid;         /* frame numbers */
    int *frmto;         /* frame 'to' fields */
    char *defn;         /* synset gloss (definition) */
    unsigned int key;       /* unique synset key */

    /* these fields are used if a data structure is returned
       instead of a text buffer */

    struct ss *nextss;      /* ptr to next synset containing searchword */
    struct ss *nextform;    /* ptr to list of synsets for alternate
                   spelling of wordform */
    int searchtype;     /* type of search performed */
    struct ss *ptrlist;     /* ptr to synset list result of search */
    char *headword;     /* if pos is "s", this is cluster head word */
    short headsense;        /* sense number of headword */
} Synset;

typedef Synset *SynsetPtr;


/* Primary search algorithm for use with programs (returns data structure) */
extern SynsetPtr findtheinfo_ds(char *, int, int, int); 

/* Recursive search algorithm to trace a pointer tree and return results
   in linked list of data structures. */
SynsetPtr traceptrs_ds(SynsetPtr, int, int, int);

/* Free a synset linked list allocated by findtheinfo_ds() */
extern void free_syns(SynsetPtr);   

/* Free a synset */
extern void free_synset(SynsetPtr); 

这基本上就是我所知道的。

编辑 2:

尽管我已经使用了下面的两个答案,不幸的是,这些函数仍然在泄漏字节。

这似乎只发生在:

traceptrs_ds ( ptr, SIMPTR, ADJ, 0 )

文档中关于形容词同义词 (-synsa) 或其他类型(-synsn、-synsv)的信息非常少。

但是,我设法迭代了其中的大部分,只需遵循 ptr->ptrlist && ptr->nextss;

traceptr_ds 迭代了它们的 ALL,但我找不到避免泄漏的方法,即使使用缩小的测试程序也是如此。

感谢提供帮助的人,非常感谢。

最佳答案

您可以为此目的使用 std::shared_ptr,因为您可以提供删除器 来释放指针。

std::shared_ptr<Synset> findTheInfo(...) {
    std::shared_ptr<Synset> sp(findtheinfo(...), free_syns);
    return sp;
}
std::shared_ptr<Synset> tracePtrs(...) {
    std::shared_ptr<Synset> sp(traceptrs(...), free_synset);
    return sp;
}

现在,如果它们真的代表不同的事物,您可能需要多花点功夫并提供两种类型来包装每次使用并提供适当的接口(interface)。在遍历列表和树可能完全不同时将两者视为同一类型是否有意义?

关于c++ - 在 C++11 中使用智能指针环绕旧的 C 结构并自动释放它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21745260/

相关文章:

c++ - 重载模板关系运算符

c - Makefile 产生错误 "No rule to make target"

c - 如何在C中为插入排序算法实现结构交换

c# - 快速替换Win32_NetworkAdapter WMI类以获取本地计算机的MAC地址

c++ - 在 C++ 中使用 Cairo 渲染亚洲字符?

c - 左值 : array and structure

C++ 将 double 转换为 char 并替换为 std::array

模板内的 C++ 编译时偏移量

c++ - 使用 boost::future 和 "then"延续

c++ - 在 opencv2/3 中清除图像的最有效方法