2

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);

そしてその下のコード。

このセグメンテーション違反が発生している理由について、誰かが私を助けてくれますか?

私は何かが欠けていることを知っていますが、それが何であるかを理解できません。

4

1 に答える 1

2

Python docs のこの例に基づいて、完全に初期化された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 */
}; 

例で説明しているように、 sizeof(noddy_NoddyObject) に設定されたメンバーは、新しいオブジェクトに割り当てるメモリ量を知るために PyObject_New によって使用されます。staticforward は static になるマクロだと思います。つまり、

staticforward PyTypeObject linked_list_type;

すべてのフィールドがゼロに初期化された状態で作成されるため、PyObject_New は新しいオブジェクトに 0 バイトを割り当てようとします。したがって、そのオブジェクトのフィールドにアクセスすると、所有していないメモリにアクセスすることになり、その結果、セグメンテーション違反が発生します。

于 2013-04-13T10:59:33.223 に答える