首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python C-API对象初始化

Python C-API对象初始化
EN

Stack Overflow用户
提问于 2009-02-24 10:43:49
回答 3查看 1.1K关注 0票数 1

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

我尝试了这段代码,但是它导致调试版本出现访问冲突,因为没有设置_ob_prev和_ob_next。

代码语言:javascript
复制
//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行

代码语言:javascript
复制
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);
}
EN

回答 3

Stack Overflow用户

发布于 2009-12-27 09:32:02

我们正在做的事情是非常可怕的。除非这个代码路径对性能非常关键,否则我建议您像往常一样在堆上分配对象。

票数 1
EN

Stack Overflow用户

发布于 2009-02-26 00:38:03

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

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

你可以用普通的方式管理你的python对象,但是在其中存储指向你自己管理的内存中数据的指针。

放眼全局..。你为什么要这么做呢?

另外,你的评论是

我尝试过此代码,但它导致调试版本出现访问冲突,因为未设置_ob_prev和_ob_next。.

代码语言:javascript
复制
//couldnt get PyObject_HEAD_INIT or PyVarObject_HEAD_INIT to compile
//however the macros resolve to this

是令人担忧的!在讨论更高级的内容之前,您是否成功地定义了使用标准内存管理的类型?

票数 0
EN

Stack Overflow用户

发布于 2009-03-30 21:35:32

你可以看看Py_NoneStruct是如何做到这一点的。您的代码看起来基本上是正确的。

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

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/581281

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档