ocaml - C 接口:failwith() 是否泄漏内存?
问题描述
我正在尝试使用使用 camlidl 生成的 C 接口。我正在使用的库通过分配和填充输入/输出参数char* error_message
并返回它来返回错误代码。在函数调用之后,我检查错误代码是否非零......如果为真,我调用caml_failwith(error_message)
以使用库错误消息引发 OCaml 异常。
但是,我开始深入研究,因为抛出异常看起来好像它会终止函数并且永远不会释放错误消息。考虑这个模拟代码:
/* in the C stub function call... */
double _res;
int error = 0;
char* error_message = NULL;
// if this function errors, it will set error to non-zero
// and strdup something into error_message
_res = call_library_function(&error, error_message);
if (error) {
caml_failwith(error_message);
free(error_message); // NEVER CALLED?
}
/* code to copy result to an OCaml value and return */
异常 funccaml_failwith(s)
实现是 in runtime/fail_*.c
,但它基本上只是调用caml_raise_with_string
,即:
CAMLparam1(tag);
value v_msg = caml_copy_string(msg);
caml_raise_with_arg(tag, v_msg);
CAMLnoreturn;
因此,它使用 caml_copy_string 将字符串复制到 OCaml 值,然后引发 arg 并且不返回。简而言之,error_message is lost。
...正确的?我在这里错过了什么......我可以使用罐装字符串,但这使得动态错误消息变得不可能。我也许可以使用静态 char*,尽管如果没有大量工作,它就不再是线程安全的了。 有什么方法可以调用caml_failwith
,使用普通的旧动态char*
,并且不会导致泄漏?
编辑:我想到了一种解决方案......
char error_message_buf[100] = {'\0'};
double _res;
// ... rest of local vars and service call ...
if (error) {
strncpy(error_message_buf, error_message, 99)
free(error_message);
caml_failwith(error_message_buf);
}
……但那是丑陋的人。 strncpy
到堆栈只是为了一次又一次地转身caml_copy_string
?另外,它设置了错误消息长度的硬编码上限。不过,如果这是不泄漏的唯一方法......
解决方案
caml_failwith()
被设计成你可以用一个常量字符串来调用它,这是一种非常常见的情况:
caml_failwith("float_of_string");
所以,你不能指望它释放它的论点。
我个人不认为这是空间泄漏,这只是功能的设计方式。
您首先复制消息的解决方案对我来说似乎是合理的(而且不是特别难看)。
(本质上,这就是我多年前从 C 切换到 OCaml 的原因。)
推荐阅读
- spring-boot - Hikari - Spring Boot 忽略了 hikari 属性
- javascript - 如何使用 Vue/Element-UI 过滤表格
- c# - 根据对象的类型为给定对象提供特定的全局索引(C#)
- java - 类型安全的 Map 与其值的多种类型的合并;`不兼容的类型 java.lang.Object 不能转换为 capture#1 of ?`
- java - 在 SOAP Ui java 中附加多个 xml 文件
- sccm - 目前在任何服务器上都找不到该软件:sccm 问题
- php - 试图从 API 获取“非对象”的属性 - json_decode
- css - Ngbootstrap:如何在搜索输入下定位下拉菜单
- flutter - 在对话框内颤动 webview
- javascript - 运行 Javascript 函数同步