缠绕旧的C结构与智能指针在C ++ 11和自动释放他们 [英] Wrapping around old C Structures with smart pointers in C++11 and auto-freeing them
问题描述
我使用字网,老C库由普林斯顿大学在九十年代开发的回来。
该库是用C语言编写,并且只显示标题而不是它的实际执行。
I'm using Word-Net, an old C library developed by Princeton University back in the nineties. The library is written in C, and only reveals the headers but not its actual implementation.
我使用的唯一的结构是:
The only structure I use is:
SynsetPtr
和两个功能我称之为是:
And the two functions I call are:
findtheinfo_ds
traceptrs_ds
这两项函数返回一个SynsetPtr。
Both those functions return a SynsetPtr.
Howevever,当SynsetPtr重新presents感名单,我必须释放它使用
Howevever, when the SynsetPtr represents a sense list, I have to free it using
free_syns
然而,当SynsetPtr用于遍历链表(层次树),我必须释放它使用
Whereas, when the SynsetPtr is used to traverse a linked list (a hierarchical tree), I have to free it using
free_synset
借助文档是真不明白这时候打电话,和这是为什么。
The Documentation is not really clear when to call which, and why.
这是迅速成为了我的噩梦。我已经花了三天时间通过泄漏,双重的FreeS,内存分配和等。
This is quickly becoming a nightmare for me. I have spent three days working my way slowly through leaks, double frees, memory allocations and such.
所以我想知道,是有我的方式,环绕这些功能,或实际结构,使C ++管理内存?理想我希望他们free'd时,有对他们没有更多的参考,如与的std :: shared_ptr的情况。
So I was wondering, is there a way for me, to wrap around those functions, or the actual Structure, and make C++ manage the memory? Ideally I would want them free'd when there are no more references to them, as is the case with std::shared_ptr.
这是可能的,知道Synset_Ptr没有析构函数,而是一个dealloc的函数被调用?
Is this possible, knowing that Synset_Ptr has no destructor, but a dealloc function has to be called?
另外,我可以环绕两个函数用于创建(分配)的结构,在某种程度上书保持的对象,并摧毁他们,当他们没有引用保持?
Alternatively, could I wrap around the two functions that create (allocate) those structures, somehow book-keep the objects, and destroy them when no references to them remain?
我真的AP preciate任何任何帮助!
I would really appreciate any help whatsoever!
编辑:
这是SynsetPtr在wn.h确切的声明
This is the exact declaration of SynsetPtr in wn.h
/* 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);
这基本上是我所知道的。
And that is essentially all I know.
编辑2:
虽然我用下面的两个答案,可惜的是,该功能仍然漏水字节。
Even though I've used the two answers below, unfortunatelly, the functions are still leaking bytes.
这似乎只发生与
traceptrs_ds ( ptr, SIMPTR, ADJ, 0 )
该文档有大约形容词同义词(-synsa)或其他类型(-synsn,-synsv)。
The documentation has very little information about adjective synonyms (-synsa) or other types (-synsn, -synsv).
不过,我设法迭代的最他们,只需遵循ptr-> ptrlist和放大器;&安培; ptr-> nextss;
However, I managed to iterate most of them, simply by following the ptr->ptrlist && ptr->nextss;
traceptr_ds迭代全部他们,但我不能找到一种方法,以避免泄漏,使用缩小的测试PROG时也是如此。
traceptr_ds iterates ALL of them, but I cannot find a way to avoid the leak, even when using a minified test prog.
感谢谁帮助了非常多的AP preciated。
Thanks to the whoever helped, very much appreciated.
推荐答案
我知道如何解决这个问题的唯一所有权,使用的unique_ptr
的漂亮的功能,其中它的管理类型将成为的删除::指针
,而不是 T *
,如果前者存在。
I know how to solve this problem for unique ownership, using unique_ptr
's nifty feature where its managed type becomes Deleter::pointer
, instead of T*
, if the former type exists.
假设你没有同义词集
的定义,或任何类型的 SynsetPtr
点的问题使用的shared_ptr
是,它没有开关的托管类型相同的设备,如果你创建一个的shared_ptr< SynsetPtr>
,构造会想到 SynsetPtr *
,但你的C API函数不返回该类型。我不知道自己是否使用的shared_ptr< remove_pointer< SynsetPtr> ::类型>
会,如果你没有这样的取消引用类型的定义编译 SynsetPtr
收益率。
Assuming you don't have the definition of Synset
, or whatever type SynsetPtr
points to, the problem with using a shared_ptr
is that it doesn't have the same facility of switching the managed type, and if you create a shared_ptr<SynsetPtr>
, the constructor will expect a SynsetPtr*
, but your C API functions don't return that type. And I don't know for sure whether using shared_ptr<remove_pointer<SynsetPtr>::type>
will compile if you don't have the definition of the type that dereferencing a SynsetPtr
yields.
此的可能的工作,但是我不知道。
This might work, but I'm not sure.
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);
}
走出独特的所有权路线,我会做一对夫妇的工厂函数返回的unique_ptr
常务 SynsetPtr
秒。
我们需要为不同类型的2个独立的删除器 SynsetPtr
取值
We need 2 separate deleters for the different kinds of SynsetPtr
s
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结构与智能指针在C ++ 11和自动释放他们的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!