在 C++11 中使用智能指针包装旧的 C 结构并自动释放它们

2023-12-03

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

我使用的唯一结构是:

SynsetPtr

我调用的两个函数是:

findtheinfo_ds

traceptrs_ds

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

然而,当 SynsetPtr 表示一个意义列表时,我必须使用它来释放它

free_syns

然而,当 SynsetPtr 用于遍历链接列表(层次树)时,我必须使用

free_synset

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

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

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

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

或者,我可以围绕创建(分配)这些结构的两个函数,以某种方式保存对象,并在没有对它们的引用时销毁它们吗?

我真的很感激任何帮助!

EDIT:

这是 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); 

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

EDIT 2:

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

这似乎只发生在:

traceptrs_ds ( ptr, SIMPTR, ADJ, 0 )

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

但是,我设法迭代most其中,只需遵循 ptr->ptrlist && ptr->nextss;

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

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


您可以使用std::shared_ptr为此,您可以提供deleter用于释放指针。

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;
}

现在,如果它们确实代表不同的事物,您可能需要花费更多的精力并提供两种类型来包装每个用途并提供适当的接口。当遍历列表时将两者视为相同类型是否有意义,而树可能完全不同?

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 C++11 中使用智能指针包装旧的 C 结构并自动释放它们 的相关文章

随机推荐

  • ECDH Nodejs 和 C# 密钥交换

    我迷失了自我 我需要帮助才能走上正确的方向 我有一个 Nodejs 服务器 它必须与用 C 编写的服务器交换一些关键数据 所以在这种情况下 我希望我的数据以某种方式加密 我正在考虑 AES 为了安全地交换密钥 我想使用 ECDH 但我不知道
  • Aptana 不会为类中的函数生成 phpdoc 块

    在 Aptana 中 我以某种方式破坏了为类中的函数自动生成 phpdoc 注释的功能 它似乎只影响我当前的项目 通常我可以在函数之前的行上输入 并按 Enter 键 Aptana 将使用正确的 param 值等创建一个 phpdoc 注释
  • Jupyter 中的内联动画

    我有一个 python 动画脚本 使用 matplotlib 的 funcAnimation 它在 Spyder 中运行 但不在 Jupyter 中运行 我尝试过遵循各种建议 例如添加 matplotlib inline 并将 matplo
  • 分配与全局变量同名的局部变量时出错

    将全局函数或局部封闭函数分配给同名的局部变量时 我看到错误 下面的代码说明了这个问题 其中f 运行良好 同时g 引发错误 看来 python 知道这一点a正在本地分配 因此它表示所有对a现在都是本地的 甚至之前的参考文献a实际上是本地分配的
  • 在 eclipse 中运行 scala 的配置

    嗨 我必须运行一个 scala 程序 我收到错误主类未找到 然后我打开首选项并在 scala 应用程序中 主类列未指定主类 你能告诉我我必须在该栏中填写什么才能运行我的程序吗 请帮助我 提前致谢 您能提供任何额外信息吗 我刚刚创建了一个 S
  • 递归对象和原子对象的定义是什么?

    R 文档 says is atomic回报TRUE if x是原子类型 或NULL and FALSE否则 is recursive回报TRUE if x有一个递归 list类似 结构 和FALSE否则 is atomic对于原子类型是正确
  • 如何反转 JavaScript 中的正则表达式?

    我有一个字符串 A 想测试另一个字符串 B 是否不属于它 这是一个非常 简单的正则表达式 其结果可以在之后反转 我可以做 foobar test email protected 然后反转它 如下所示 foobar test email pr
  • 为什么只有 1 行的 DataTable.Load 结果表现得好像是 DataRow 而不是 DataTable?

    我想查询不同服务器上的两个数据库以获取相同类型的信息 并将结果合并到一个列表中 我创建了这个示例 它可以工作 但前提是第一个服务器至少返回two rows 该示例使用整数列表 1 5 但我连接两个字符串列表的原始代码也存在相同的问题 qui
  • Mac OS X:我应该在哪里存储作为捆绑包提供的游戏的保存游戏?

    我正在将 Windows 游戏移植到 Mac OS X 我想知道应该在哪里存储游戏数据 例如保存的游戏 用户配置文件等 以及如何在 C 中以编程方式检索该路径 该游戏将按照规定作为 现代捆绑包 提供here 保存在下面 库 应用程序支持 您
  • 如何获得唯一的智能卡ID?

    我正在寻找一种方法来为我使用的每张智能卡找到唯一的号码 我听说每张卡都有唯一的 IC 制造日期 IC 序列号和 IC 批次标识符 我如何从我的卡中获取这些信息 当然 每个硬件供应商都会将上述信息集成到芯片中 不幸的是 这留下了以下问题 操作
  • (单元)测试 python 信号处理程序

    我有一个简单的 Python 服务 其中有一个无限执行某些操作的循环 根据各种信号 sys exit 0 被称为 这导致SystemExit如果可以的话 应该进行一些清理 在测试中 即标准unittest TestCase 我想测试此清理是
  • postgres 中索引元组的最大大小是多少?

    我引用的是https www postgresql org docs 11 sql createindex html关于INCLUDE clause 在向索引添加非键列 尤其是宽列 时保持保守是明智的做法 如果索引元组超过索引类型允许的最大
  • 如何关闭 show() 窗口但保持图形处于活动状态?

    如果我创建一个图形然后执行 plt close from matplotlib import pyplot as plt fig1 plt figure fig2 plt figure fig1 show plt close fig1 sh
  • 在chart.js中,如果从移动设备访问,是否可以隐藏条形图的x轴标签/文本?

    在chart js中 是否可以隐藏x axis如果从移动设备访问 则条形图的标签 文本 我想隐藏 删除标签x axis即 一月 二月 等 他们添加了这个选项 2 1 4 也许更早一点 有它 var myLineChart new Chart
  • 执行指令和读/写数据时,x86 如何处理字节寻址和字寻址?

    所以我正在学习 x86 的工作原理 并且遇到过人们说它是字节寻址的 但可以读取字 双字等 处理器如何决定使用哪种方法以及何时使用 例如 为了访问下一条指令以及当用户想要读 写存储器时 使用哪种寻址模式 每个内存访问都有一个由机器代码指令指定
  • OData 模型不起作用

    我正在尝试使用expand我的 XML 视图中的选项 但它没有产生任何数据 正如我在 网络 选项下的调试中看到的那样 数据来自后端 但 XML 视图中似乎存在一些绑定问题 组件 js sap ui define sap ui core UI
  • npm 相当于纱线分辨率?

    有没有一个npm相当于纱线分辨率功能 npm package json 中没有提及它docs 例如我想安装 email protected 以及 3 3 2 中的依赖项之一 lerna publish 目前正在这样做yarn像这样 但更喜欢
  • 如何在python中修改指定位置添加多行?

    我有一个数据框 我想按以下方式复制和行 d pd DataFrame col1 a b c d col2 12 13 14 16 所需输出 想要复制行 a1 a2 b1 b2 col1 col2 a 12 a1 12 a2 12 b 12
  • Pythonic 自定义排序字母等级“D”、“C-”、...、“A+”?

    有没有比这更 Pythonic 紧凑 直观的方法来对字母等级进行排序 不使用自定义字典 grades B C B C A D B C A D A sorted grades key lambda g g 0 index g 1 A A A
  • 在 C++11 中使用智能指针包装旧的 C 结构并自动释放它们

    我在用着Word Net 一个由普林斯顿大学在九十年代开发的旧 C 库 该库是用 C 编写的 仅显示标头 但不显示其实际实现 我使用的唯一结构是 SynsetPtr 我调用的两个函数是 findtheinfo ds traceptrs ds