使用PyObject_New进行分段错误

时间:2013-04-13 09:56:00

标签: c data-structures python-2.7 segmentation-fault cython

我正在尝试为python编写C扩展。 这个扩展基本上只是一个双链表。

以下是我写的代码: -

staticforward PyTypeObject linked_list_type;

typedef struct _linked_list_object{
    PyObject_HEAD
    int val;
    struct _linked_list_object *prev;
    struct _linked_list_object *next;
} linked_list_object;

//this method adds a new node to the linked list
static linked_list_object* add_node(linked_list_object * obj, int val)
{
    linked_list_object* new;

    new = PyObject_New(linked_list_object, &linked_list_type);
    if (new){
        new->val = val;
        if (obj)
        {
            new->prev = obj;
            new->next = obj->next;
            obj->next = new;
            new->next->prev = new;
        }
        else{
            new->next = new;
            new->prev = new;
        }
        return new;
        }
        else
        {
        return NULL;
        }

编译完这个模块并将其导入python。

代码会引发分段错误。

>>> import linked_list
Segmentation fault: 11 (core dumped)

我注意到,如果我注释掉

,则不会生成此分段错误
new = PyObject_New(linked_list_object, &linked_list_type);

以及它下面的代码。

有人可以帮助我解决为什么会出现这种细分错误吗?

我知道我错过了一些东西,但我无法弄清楚它是什么。

1 个答案:

答案 0 :(得分:2)

根据Python文档中的this example,我认为问题在于您没有提供完全初始化的linked_list_type。

在该示例中,noddy_NoddyType相当于您的代码中的linked_list_type,您会看到它们位于顶部:

staticforward PyTypeObject noddy_NoddyType;
和你一样。

然而,他们进一步向下:

static PyTypeObject noddy_NoddyType = {
    PyObject_HEAD_INIT(NULL)
    0,
    "Noddy",
    sizeof(noddy_NoddyObject),
    0,
    noddy_noddy_dealloc, /*tp_dealloc*/
    0,          /*tp_print*/
    0,          /*tp_getattr*/
    0,          /*tp_setattr*/
    0,          /*tp_compare*/
    0,          /*tp_repr*/
    0,          /*tp_as_number*/
    0,          /*tp_as_sequence*/
    0,          /*tp_as_mapping*/
    0,          /*tp_hash */
}; 

如示例所示,PyObject_New使用设置为sizeof(noddy_NoddyObject)的成员来了解为新对象分配的内存量。我相信staticforward是一个变成静态的宏,这意味着

staticforward PyTypeObject linked_list_type;

将创建所有字段初始化为零,因此PyObject_New将尝试为新对象分配0个字节。因此,访问该对象的任何字段涉及访问您不拥有的内存,结果是分段错误。