我在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;
}