PyList_New alloc items 大于实际使用的,如何初始化那些未使用的items?

PyList_New alloc items number greater than real used, how to initialize those unused items?

我有一个 C 程序可以使用 python 嵌入式。

在我的 C 代码中,我使用 PyList_New(10) 来分配 10 个项目,并使用 PyList_SetItem() 来初始化它们,但实际上我可能不会使用所有它们(例如,我使用了 8)。所以事实是列表项中的 8 个已经初始化,其中 2 个没有(在 C 代码中它们将是 NULL)。初始化后,我用 PyObject_Call() 调用了一个 python 函数。最后,我的程序在 python 脚本中被破坏了,因为 NULL 指针。

所以,我想知道如何初始化 2 个未使用的项目(也许将其转换为 None)

PS:不想用PyList_Append,因为听说效率有点低

我的C代码是这样的:

PyObject *py_func;

int my_func(PyObject *item_value)
{
    my_list = PyList_New(10);

    for (i = 0; i < 8; i++) {
        PyList_SetItem(my_list, i, item_value);
    }

    /* ... */
    PyObject_Call(py_func, my_list, NULL);

    /* ... */
    return 0;
}

我的python代码是这样的:

def my_func(aList):
    for item in aList:
        if item:
            # do something

========================================

这里是 python 解释器损坏的堆栈:

Program terminated with signal SIGSEGV, Segmentation fault.
#0  listiter_next (it=0x7f354defe5c0) at Objects/listobject.c:2782
2782    Objects/listobject.c: No such file or directory.
[Current thread is 1 (Thread 0x7f3558c2e840 (LWP 607))]
(gdb) bt
#0  listiter_next (it=0x7f354defe5c0) at Objects/listobject.c:2782
#1  0x00007f355840cbaa in _PyEval_EvalFrameDefault (f=<optimized out>, 
    throwflag=<optimized out>) at Python/ceval.c:3071
#2  0x00007f3558407b6e in _PyEval_EvalCodeWithName (_co=0x7f3558aba780, 
    globals=<optimized out>, locals=locals@entry=0x0, 
    args=args@entry=0x7f35501b2fe0, argcount=2, kwnames=kwnames@entry=0x0, 
    kwargs=kwargs@entry=0x8, kwcount=kwcount@entry=0, kwstep=kwstep@entry=2, 
    defs=defs@entry=0x0, defcount=defcount@entry=0, kwdefs=kwdefs@entry=0x0, 
    closure=closure@entry=0x0, name=name@entry=0x0, 
    qualname=qualname@entry=0x0) at Python/ceval.c:4139
#3  0x00007f3558408193 in PyEval_EvalCodeEx (_co=<optimized out>, 
    globals=<optimized out>, locals=locals@entry=0x0, 
    args=args@entry=0x7f35501b2fe0, argcount=<optimized out>, 
    kws=kws@entry=0x0, kwcount=kwcount@entry=0, defs=defs@entry=0x0, 
    defcount=defcount@entry=0, kwdefs=0x0, closure=0x0) at Python/ceval.c:4160
#4  0x00007f3558349076 in function_call (func=0x7f3550a20268, 
    arg=0x7f35501b2fc8, kw=0x0) at Objects/funcobject.c:604
#5  0x00007f3558316c2a in PyObject_Call (func=0x7f3550a20268, 
    args=<optimized out>, kwargs=<optimized out>) at Objects/abstract.c:2246

我不明白你的 Python 和 C 代码如何与两者中定义的 my_func 结合在一起,但如果你的问题确实来自列表中未初始化的值,那是因为你没有' 将它们初始化为 Python 中有效的内容。 C NULL 指针不是。 Py_None 是。来自文档:

Py_None is the C name for the special Python object None. It is a genuine Python object rather than a NULL pointer, which means “error” in most contexts, as we have seen.

因此,只需将列表的其余元素设置为 Py_None(使用 Py_INCREF)即可。

for (i = 0; i < 8; i++) {
    PyList_SetItem(my_list, i, item_value);
}
for (; i < PyList_Size(my_list); i++) {
    Py_INCREF(Py_None);
    PyList_SetItem(my_list, i, Py_None);
}