扩展python3,垃圾收集如何工作

时间:2016-03-24 13:35:05

标签: c++ c python-3.x module garbage-collection

我在C中创建自己的PriorityQueue作为python模块。我阅读了python所有权和参考系统的基础知识,所以我想我会做以下事情:

push()中:接受优先级(int)和要保存的对象。增加要保存的对象的引用计数,因为我们将保留它。

pop()中:从我的priorityqueue中删除对象,但不减少引用计数器,因为这可能会破坏对象。相反,我将我的引用所有权转移到调用我的函数的python函数。

这似乎是第一手工作。但是当在应用程序中实际使用它时,我收到以下错误: 致命Python错误:已跟踪GC对象

这是什么意思?堆栈跟踪根本没用,它都是我无法识别的python文件(sre_parse和apport_python_hook)。

为了清楚起见,这些是我的C推送和弹出功能: (self->heap[index]->key是该索引处元素的优先级  self->heap[index]->value是对象)

PyObject* pop(CDSHeap *self) {
    //If there aare no elements
    if (self->heap[0].value == 0 || self->end == 0) {
        Py_RETURN_NONE;
    }
    //If there is only one element
    if (self->end == 1) {
        PyObject* result = self->heap[0].value;
        self->heap[0].key = 0;
        self->end = 0;
        return result;
    }
    //Two or more elements:
    //First save the result:
    PyObject* result = self->heap[0].value;
    //Get the last element, and place it at the top
    while (self->heap[self->end].value == 0) self->end--;
    self->heap[0].value = self->heap[self->end].value;
    self->heap[0].key = self->heap[self->end].key;
    self->heap[self->end].value = 0;
    //Reheapify the heap
    int ptr = 0;
    while (self->end >= ptr) {
        if (self->heap[ptr*2+1].value != 0 && self->heap[ptr*2+1].key < self->heap[ptr].key
        && (self->heap[ptr*2+2].value == 0 || self->heap[ptr*2+1].key <= self->heap[ptr*2+2].key)) {
            swapElement(self->heap, ptr, ptr*2+1);
            ptr = ptr*2+1;
        }else 
        if (self->heap[ptr*2+2].value != 0 && self->heap[ptr*2+2].value < self->heap[ptr].value) {
            swapElement(self->heap, ptr, ptr*2+2); 
            ptr = ptr*2+2;
        } else {
            break;
        }
    }   
    return result;
}

PyObject* push(CDSHeap *self, PyObject* args) {
    int k;
    PyObject *obj;
    if (!PyArg_ParseTuple(args, "iO",&k, &obj)){
        return NULL;
    }   
    Py_INCREF(obj);

    //Add the element to the end of the heap
    self->heap[self->end].key = k;
    self->heap[self->end].value = obj;
    //Increment the size and reheapify
    int ptr = self->end++;
    while (ptr > 0) {
        int parent = (ptr-1)/2;
        if (self->heap[ptr].key < self->heap[parent].key) {
            swapElement(self->heap, ptr, parent);
            ptr = parent;
        } else {
            Py_RETURN_NONE;
        }
    }
    Py_RETURN_NONE;
}

0 个答案:

没有答案