用C 11中的智能指针包装旧的C结构并自动释放它们
作者:互联网
我使用的是Word-Net,这是普林斯顿大学90年代开发的旧C库.
该库是用C编写的,仅显示标头,而不显示其实际实现.
我使用的唯一结构是:
SynsetPtr
我调用的两个函数是:
findtheinfo_ds
traceptrs_ds
这两个函数均返回SynsetPtr.
但是,当SynsetPtr代表一个感应列表时,我必须使用
free_syns
而当SynsetPtr用于遍历链接列表(层次树)时,我必须使用
free_synset
Documentation不清楚何时呼叫以及为何呼叫.
这对我来说迅速成为一场噩梦.我花了三天的时间慢慢解决泄漏,两次释放,内存分配等问题.
所以我想知道,有没有办法让我包装这些函数或实际的Structure,并让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迭代所有这些,但是即使使用缩小的测试编,我也找不到避免泄漏的方法.
感谢谁的帮助,非常感谢.
解决方法:
我知道如何使用unique_ptr的巧妙功能解决此问题,该功能的托管类型变为Deleter :: pointer,而不是T *(如果存在前一种类型).
假设您没有Synset的定义或SynsetPtr指向的任何类型,则使用shared_ptr的问题在于它没有切换托管类型的相同功能,并且如果创建了shared_ptr< SynsetPtr> ;,构造函数会期望使用SynsetPtr *,但是您的C API函数不会返回该类型.而且我不确定是否使用shared_ptr< remove_pointer< SynsetPtr> :: type>如果您没有解引用SynsetPtr产生的类型的定义,则将编译.
这可能有效,但我不确定.
std::shared_ptr<std::remove_pointer<SynsetPtr>::type>
make_findtheinfo_ds(char *searchstr, int pos, int ptr_type, int sense_num)
{
return std::shared_ptr<std::remove_pointer<SynsetPtr>::type>
(findtheinfo_ds(searchstr, pos, ptr_type, sense_num),
free_syns);
}
std::shared_ptr<std::remove_pointer<SynsetPtr>::type>
make_traceptrs_ds(SynsetPtr synptr, int ptr_type, int pos, int depth)
{
return std::shared_ptr<std::remove_pointer<SynsetPtr>::type>
(traceptrs_ds(synptr, ptr_type, pos, depth),
free_synset);
}
沿着唯一的所有权路线,我将创建几个工厂函数,这些函数返回管理SynsetPtrs的unique_ptrs.
对于不同种类的SynsetPtr,我们需要2个单独的删除器
struct sense_list_del
{
using pointer = SynsetPtr;
void operator()(SynsetPtr p)
{
free_syns(p);
}
};
struct linked_list_del
{
using pointer = SynsetPtr;
void operator()(SynsetPtr p)
{
free_synset(p);
}
};
std::unique_ptr<SynsetPtr, sense_list_del>
make_findtheinfo_ds(char *searchstr, int pos, int ptr_type, int sense_num)
{
return std::unique_ptr<SynsetPtr, sense_list_del>
(findtheinfo_ds(searchstr, pos, ptr_type, sense_num));
}
std::unique_ptr<SynsetPtr, linked_list_del>
make_traceptrs_ds(SynsetPtr synptr, int ptr_type, int pos, int depth)
{
return std::unique_ptr<SynsetPtr, linked_list_del>
(traceptrs_ds(synptr, ptr_type, pos, depth));
}
标签:c-3,wordnet,c,c11 来源: https://codeday.me/bug/20191011/1891016.html