{tp_alloc, tp_dealloc} 和 {tp_new, tp_free} 是否应被视为对
Should {tp_alloc, tp_dealloc} and {tp_new, tp_free} be considered as pairs?
tp_alloc中创建的任何内容都应该在tp_dealloc中销毁吗? 同样,对于{tp_new,tp_free}?
它看起来像一个明显的对称性,但我希望得到澄清。
我的实际用例是这样的:我有:
class OSClass : PyObject {...}
class Final : OSClass {...}
所以相应的PyTypeObject pto
有:
pto->tp_basicsize = sizeof(FinalClass)
pto->tp_dealloc = (destructor)
[](PyObject* pyob) { PyMem_Free(pyob); };
但是,新的样式类将 PyObject 及其相应的 C++ 对象彼此分开存储,因此工作方式不同。
它在tp_new中创建 PyObject,在tp_init中创建相应的 C++ 对象。
并在tp_dealloc中摧毁了他们两个
这是正确/最佳的吗?
法典:
// extra void* to point to corresponding C++ object
pto->tp_basicsize = sizeof(PyObject) + sizeof(void*)
pto->tp_new = new_func;
pto->tp_init = init_func;
pto->tp_dealloc = dealloc_func;
static PyObject* new_func( PyTypeObject* subtype, PyObject* args, PyObject* kwds )
{
// First we create the Python object.
// The type-object's tp_basicsize is set to sizeof(Bridge)
// (Note: We could maybe use PyType_GenericNew for this:
// http://stackoverflow.com/questions/573275/python-c-api-object-allocation )
//
PyObject* pyob = subtype->tp_alloc(subtype,0);
Bridge* bridge = reinterpret_cast<Bridge*>(pyob);
// We construct the C++ object later in init_func (below)
bridge->m_pycxx_object = nullptr;
return pyob;
}
static int init_func( PyObject* self, PyObject* args, PyObject* kwds )
{
try
{
Object a = to_tuple(args);
Object k = to_dict(kwds);
Bridge* bridge{ reinterpret_cast<Bridge*>(self) };
// NOTE: observe this is where we invoke the
// constructor, but indirectly (i.e. through final)
bridge->m_pycxx_object = new FinalClass{ bridge, a, k };
}
catch( Exception & )
{
return -1;
}
return 0;
}
static void dealloc_func( PyObject* pyob )
{
auto final = static_cast<FinalClass*>( cxxbase_for(pyob) );
delete final;
PyMem_Free(pyob);
COUT( "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" );
//self->ob_type->tp_free(self);
}
从您拥有的tp_new
文档中
tp_new函数应调用
subtype->tp_alloc(subtype, nitems)
为对象分配空间,然后仅执行绝对必要的进一步初始化。可以安全忽略或重复的初始化应放在tp_init处理程序中。一个好的经验法则是,对于不可变类型,所有初始化都应在tp_new中进行,而对于可变类型,大多数初始化应推迟到tp_init。
这就是为什么您在 tp_new
中创建对象本身并在 tp_init
中初始化它的原因。创建C++对象是初始化的一部分。由于tp_init
文档指出
此函数对应于类的 __init__() 方法。与 __init__() 一样,可以在不调用 __init__() 的情况下创建实例,并且可以通过再次调用其 __init__() 方法来重新初始化实例。
您需要检查bridge->m_pycxx_object != nullptr
并在失败或引发错误时删除已初始化的实例。
在tp_dealloc
中,您将销毁 Python 对象。由于C++对象是此对象的一部分,因此也需要在那里销毁它。
回到配对:您在tp_new
内调用tp_alloc
,在tp_dealloc
内调用tp_free
。所以 { tp_alloc
, tp_free
} 和 { tp_new
, tp_dealloc
} 应该被视为成对。
- 当我们从/tp地址中添加/减去一个整数时会发生什么
- 组件对象模型 (COM):IMalloc::Alloc 在哪里分配内存?
- 获取错误:在抛出"std::bad::alloc"的实例后终止调用 what(): std::bad_alloc
- 线程池的计时测试:单线程 vs 回调 tp vs 未来 tp
- CGAL:Hausdorff距离不良Alloc
- C STD ::初始化类对象中的Alloc错误错误
- 尝试解决HackerBank上的BFS挑战时出现错误的alloc异常
- 从 BSTR tp std::string 转换大字符串
- 为背包算法使用向量时抛出了错误的alloc
- 错误 C2228:'.Alloc'左侧必须具有类/结构/联合
- 为什么 cocos2d 和 libdispatch.dylib 如此频繁地调用 alloc
- 在分配器中使用new函数和*alloc函数时,它们之间有区别吗
- 为什么'has_construct<Alloc, T, Args...>::value'在gcc(false)和clang(true)上给出不同的值?
- 如何追踪"tcmalloc : large alloc .... "
- c++中的Alloc数组,c#中的free数组
- Cppcheck认为在alloc和dealloc中存在不匹配
- C++Alloc错误将对象添加到OpenMPI For循环中的矢量(或Deque或List)
- 一个快速的new/delete和alloc/free