【问题标题】:Spot Undefined Behavior in this code snippet在此代码段中发现未定义的行为
【发布时间】:2018-01-28 13:17:32
【问题描述】:

我 90% 确定我在这里看到的奇怪结果是由我的代码触发的某种 UB,但是,我找不到它:

cdef char** to_cstring_array(strings):
    cdef char** result = <char**>malloc(len(strings) * sizeof(char*))
    cdef bytes item
    nelements = len(strings)
    i = 0

    while i < nelements:
        s = str(strings[i]).encode("utf-8")
        item = s
        result[i] = item
        i += 1
    return result


cpdef object pykubectl_get(object items, object options=None):
    cdef size_t nargs = len(items);
    cdef bytes message
    cdef char** args = to_cstring_array(items);
    # message = args[0]
    # print("1 items encoded: {}".format(message))
    json_opts = json.dumps(options or {}).encode("utf-8")
    cdef char* opts = json_opts
    print("items: {}".format(items))
    message = args[0]
    print("2 items encoded: {}".format(message))
    cdef ResourceGet_return result = kubectl_get(
        opts,
        len(json_opts),
        <const char**>args,
        nargs
    )
    free(args)

    if result.r0.n == 0:
        message = result.r1.p
        raise Exception("kubectl failed: '{}'".format(message.decode("utf-8")))
    message = result.r0.p
    return json.loads(message.decode("utf-8"))

如果我取消注释将第一个参数分配给message 的行,args 的内容会发生变化。我的猜测是编译器正在尝试优化这里的某些东西,它可能与内存分配的完成方式有关,但我看不出它有任何问题。我也知道,原则上,我不需要强制转换为const char**,但我收到了不强制转换的警告,所以我添加了它。如果我忽略警告并且不施放,它什么也不会改变。

我不会发布生成的 C 代码,因为它很大……但如果这不可避免,我会在别处发布。

【问题讨论】:

    标签: python c cython undefined-behavior


    【解决方案1】:
    result[i] = item
    

    这会创建一个指向 Python bytes 对象 item 的第一个元素的指针。它不会导致item 保持活动状态。只要item 被释放(可能在循环的下一次迭代中),指针就会立即无效。

    您需要实际复制内存 - 例如:

    cdef char* item_as_charp
        # ....
        # then in the loop
        item_as_charp = <char*>malloc(sizeof(char)*len(item))
        memcpy(item_as_charp,item, len(item))
    

    (您可能需要使用len(item)+1 为空终止符腾出空间)

    当然,一旦你完成了它,你需要释放这个内存

    【讨论】:

    • 是的,就是这样!
    猜你喜欢
    • 2018-12-14
    • 2010-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-25
    • 1970-01-01
    • 2017-01-17
    • 2014-06-22
    相关资源
    最近更新 更多