Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python C-API对象初始化_Python_C_Python 3.x_Python C Api - Fatal编程技术网

Python C-API对象初始化

Python C-API对象初始化,python,c,python-3.x,python-c-api,Python,C,Python 3.x,Python C Api,将python对象初始化到现有内存(如c++中的inplace new)的正确方法是什么 我尝试了这段代码,但是由于没有设置_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

将python对象初始化到现有内存(如c++中的inplace new)的正确方法是什么

我尝试了这段代码,但是由于没有设置_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中的第1519行

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);
}
void
_Py_ForgetReference(寄存器PyObject*op)
{
#ifdef慢速检查
寄存器PyObject*p;
#恩迪夫
if(op->ob_refcnt<0)
Y_FatalError(“UNREF负参考”);
if(op==&refchain)||
在这里,{/------//
fprintf(stderr,“*ob\n”);
_PyObject_转储(op);
fprintf(标准,“*op->\U ob\U prev->\U ob\U next\n”);
_PyObject_Dump(op->u ob_prev->u ob_next);
fprintf(标准,“*op->\U ob\U next->\U ob\U prev\n”);
_PyObject_Dump(op->u ob_next->u ob_prev);
Py_FatalError(“UNREF无效对象”);
}
#ifdef慢速检查
对于(p=refchain.\u ob\u next;p!=&refchain;p=p->\u ob\u next){
如果(p==op)
打破
}
如果(p==&refchain)/*未找到*/
Py_FatalError(“UNREF未知对象”);
#恩迪夫
op->\U ob\U next->\U ob\U prev=op->\U ob\U prev;
op->\U ob\U prev->\U ob\U next=op->\U ob\U next;
op->\u ob\u next=op->\u ob\u prev=NULL;
_皮尤公司(op);
}

直面问题,你有几个选择。快速而肮脏的方法是在初始化代码中添加一个额外的Py_INCREF。假设您没有refcount错误,refcount将永远不会返回零,释放代码将永远不会被调用,并且不会出现崩溃。(实际上,这可能是管理静态分配的内置类型对象的方式!)

您可以为您的类型编写一个自定义分配器和释放定位器,以您喜欢的方式管理内存。实际上,您可以为整个python解释器编写一个自定义分配器和解除定位器

您可以以正常的方式管理python对象,但可以在其中存储指向您自己管理的内存中的数据的指针

从更大的角度来看。。。你为什么要这么做

还有,你的评论是

我尝试了这段代码,但是由于没有设置_ob_prev和_ob_next,它会导致调试版本的访问冲突。。 及


你在担心!您是否已成功定义了一种使用标准内存管理的类型,然后再转到更高级的内容?

从表面上看,您有几个选择。快速而肮脏的方法是在初始化代码中添加一个额外的Py_INCREF。假设您没有refcount错误,refcount将永远不会返回零,释放代码将永远不会被调用,并且不会出现崩溃。(实际上,这可能是管理静态分配的内置类型对象的方式!)

您可以为您的类型编写一个自定义分配器和释放定位器,以您喜欢的方式管理内存。实际上,您可以为整个python解释器编写一个自定义分配器和解除定位器

您可以以正常的方式管理python对象,但可以在其中存储指向您自己管理的内存中的数据的指针

从更大的角度来看。。。你为什么要这么做

还有,你的评论是

我尝试了这段代码,但是由于没有设置_ob_prev和_ob_next,它会导致调试版本的访问冲突。。 及


你在担心!在转到更高级的东西之前,您是否成功定义了使用标准内存管理的类型?

您可以查看Py_nonestuct了解如何实现这一点。您的代码看起来基本正确

这是一个计数错误。静态分配的对象永远无法释放,因此永远不应调用_Py_ForgetReference


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

您可以查看Py_nonestuct了解如何完成此操作。您的代码看起来基本正确

这是一个计数错误。静态分配的对象永远无法释放,因此永远不应调用_Py_ForgetReference


如果您想释放它们,必须使用自定义分配器,而不是静态初始化。

我们正在做的事情非常可怕。除非这个代码路径真的对性能至关重要,否则我建议您像通常那样在堆上分配对象。

正在做的事情非常可怕。除非此代码路径真的对性能至关重要,否则我建议您像通常那样在堆上分配对象。

引用计数是正确的,而不是这里的问题(因此它在发布版本中工作正常)。问题是,在调试构建中,next和prev为null这一事实似乎会导致python在清理对象时崩溃,因此我似乎需要一种初始化它们的方法。我所有的类型都使用标准python内存管理(即不将tp_*类型的内容过度隐藏为内存,或使用PyObject_New*+PyObject_Del)可以正常工作(在debug和release中),我假设在所有这些情况下都设置了next和pefv指针,而这里没有。reference计数是正确的,而不是这里的问题(因此它在release构建中工作良好的原因)问题是,在调试构建中,当清理对象时,next和prev为null这一事实似乎会导致python崩溃,因此我似乎需要一种方法来初始化它们。我所有的类型都使用标准python内存管理(即不将tp_*类型的内容过度隐藏为内存,或使用PyObject_New*+PyObject_Del)可以正常工作(在debug和release中),我假设在所有这些情况下都设置了next和pefv指针,而这里没有。
//couldnt get PyObject_HEAD_INIT or PyVarObject_HEAD_INIT to compile
//however the macros resolve to this