我正在尝试为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);
以及它下面的代码。
有人可以帮助我解决为什么会出现这种细分错误吗?
我知道我错过了一些东西,但我无法弄清楚它是什么。
答案 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个字节。因此,访问该对象的任何字段涉及访问您不拥有的内存,结果是分段错误。