2009-02-24 73 views
1

什么是初始化一个Python对象到现有存储器(类似于C的就地新++)Python的C-API对象初始化

我试过但是这个代码它会导致访问冲突与调试版本,因为正确的方法在_ob_prev和_ob_next没有设置..

//PyVarObject *mem; -previously allocated memory 

Py_INCREF(type); 
//couldnt get PyObject_HEAD_INIT or PyVarObject_HEAD_INIT to compile 
//however the macros resolve to this 
PyVarObject init = {{_PyObject_EXTRA_INIT 1, ((_typeobject*)type)}, 0}; 
*mem = init; 
//...other init code for type... 

的崩溃object.c

void 
_Py_ForgetReference(register PyObject *op) 
{ 
#ifdef SLOW_UNREF_CHECK 
     register PyObject *p; 
#endif 
    if (op->ob_refcnt < 0) 
     Py_FatalError("UNREF negative refcnt"); 
    if (op == &refchain || 
     op->_ob_prev->_ob_next != op || op->_ob_next->_ob_prev != op) { //----HERE----// 
     fprintf(stderr, "* ob\n"); 
     _PyObject_Dump(op); 
     fprintf(stderr, "* op->_ob_prev->_ob_next\n"); 
     _PyObject_Dump(op->_ob_prev->_ob_next); 
     fprintf(stderr, "* op->_ob_next->_ob_prev\n"); 
     _PyObject_Dump(op->_ob_next->_ob_prev); 
     Py_FatalError("UNREF invalid object"); 
    } 
#ifdef SLOW_UNREF_CHECK 
    for (p = refchain._ob_next; p != &refchain; p = p->_ob_next) { 
     if (p == op) 
      break; 
    } 
    if (p == &refchain) /* Not found */ 
     Py_FatalError("UNREF unknown object"); 
#endif 
    op->_ob_next->_ob_prev = op->_ob_prev; 
    op->_ob_prev->_ob_next = op->_ob_next; 
    op->_ob_next = op->_ob_prev = NULL; 
    _Py_INC_TPFREES(op); 
} 

回答

0

以你的面值问题上线1519 occures,你有一个铁w选项。快速和肮脏的方法是将额外的Py_INCREF放入初始化代码中。假设你没有refcount错误,refcount永远不会回到零,deallocation代码永远不会被调用,并且不应该崩溃。 (事实上​​,这可能是静态分配内建类型对象的管理方式!)

你可以写你的类型,在您的首选方式管理存储自定义分配器和释放器。实际上你可以为整个python解释器编写一个自定义分配器和释放器。

你可以在他们管理的正常方式你的Python对象,但指针存储在您管理自己的存储数据。

纵观大局...为什么你想这样做吗?

还有,你的评论认为

我想这个代码但它会导致访问冲突与调试版本,因为_ob_prev和_ob_next没有设置..

//couldnt get PyObject_HEAD_INIT or PyVarObject_HEAD_INIT to compile 
//however the macros resolve to this

被令人担忧!在转向更高级的东西之前,您是否成功地定义了一种使用标准内存管理的类型?

+0

refrence counting是正确的,而不是这里的问题(因此它在发布版本中工作正常的原因)。问题是,在调试构建下next和prev为空的事实似乎导致python在清理对象时崩溃,所以看起来我需要一种方法来初始化它们。 – 2009-02-26 07:31:28

0

你可以看看Py_NoneStruct是如何完成的。你的代码看起来基本正确。

这是一个计数错误。静态分配的对象永远不会被释放,所以_Py_ForgetReference不应该被调用。

如果你希望能够释放他们,你必须使用使用自定义的分配,而不是静态初始化。

1

正在做的事情非常可怕。除非这段代码路径确实对性能至关重要,否则我建议你像平常一样在堆上分配对象。