代码之家  ›  专栏  ›  技术社区  ›  Greg Kennedy

C接口:failwith()是否泄漏内存?

  •  1
  • Greg Kennedy  · 技术社区  · 7 年前

    我正在尝试使用camlidl生成的C接口。我使用的库通过分配和填充in/out参数返回错误代码 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 */
    

    caml_failwith(s) 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\u copy\u string将字符串复制到OCaml值,然后提升arg,不返回。总之, .

    …对吧?我错过了什么。。。我可以使用罐装字符串,但这使得动态错误消息不可能。我可以使用static 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 再一次?此外,它还设置了错误消息长度的硬编码上限。不过,如果这是唯一不泄漏的方法。。。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Jeffrey Scofield    7 年前

    caml_failwith() 它的设计使您可以使用常量字符串调用它,这是一种非常常见的情况:

    caml_failwith("float_of_string");
    

    所以,你不能指望它释放它的论点。

    你先复制信息的方法在我看来是合理的(也不是特别难看)。

    (本质上,这就是我多年前从C转换到OCaml的原因。)

    推荐文章