为什么我在使用 Python/C API 时会出现这个段错误
Why am I getting this segfault when using the Python/C API?
使用 Python/C API 在我的C++代码中引用PyObject*
时,我遇到了分段错误,我不知道为什么。 我正在使用C++和Python 2.7。 我正在使用新样式的类来实现未来的 Python 3 兼容性。
我的目标是创建一个C++类MyClass
,作为 Python 模块中定义的类的包装器。 在MyClass
构造函数中,我传入 Python 模块的名称,导入模块,找到类(始终具有预定义的名称 PyClass
),然后调用该类来创建它的实例。 然后,我将生成的PyObject*
存储在MyClass
中以备将来使用。 在 MyClass
析构函数中,我取消了存储PyObject*
以避免内存泄漏。
我已经验证了就查找类并创建其实例而言,一切正常。 我什至验证了我可以在其他MyClass
方法中使用存储的PyObject*
,例如,访问PyClass
中的方法。 但是,当析构函数执行 decref 时,它会导致段错误。
这是我的代码示例。 我还在适当的时候在其他地方调用Py_Initialize()
和Py_Finalize()
,为了简洁起见,我省略了一些错误检查代码:
MyPythonModule.py
class PyClass:
pass
MyClass.h
class MyClass {
public:
MyClass(const char* modulename);
~MyClass();
private:
void* _StoredPtr;
};
MyClass.cpp
#include <Python.h>
#include <iostream>
#include "MyClass.h"
MyClass::MyClass(const char* modulename) {
_StoredPtr = NULL;
PyObject *pName = NULL, *pModule = NULL, *pAttr = NULL;
// Import the Python module.
pName = PyString_FromString(modulename);
if (pName == NULL) {goto error;}
pModule = PyImport_Import(pName);
if (pModule == NULL) {goto error;}
// Create a PyClass instance and store a pointer to it.
pAttr = PyObject_GetAttrString(pModule, "PyClass");
if (pAttr == NULL) {goto error;}
_StoredPtr = (void*) PyObject_CallObject(pAttr, NULL);
Py_DECREF(pAttr);
if (_StoredPtr == NULL) {goto error;}
error:
if (PyErr_Occurred()) {PyErr_Print();}
Py_XDECREF(pName);
Py_XDECREF(pModule);
return;
}
MyClass::~MyClass() {
std::cout << "Starting destructor..." << std::endl;
Py_XDECREF((PyObject*)(_StoredPtr));
std::cout << "Destructor complete." << std::endl;
}
我知道我可以通过在析构函数中省略Py_XDECREF()
来避免段错误,但我害怕导致内存泄漏,因为我不明白为什么会发生这种情况。 特别奇怪的是,我可以在其他MyClass
方法中成功地使用_StoredPtr
,但我无法拒绝它。
我还尝试将导入模块的PyObject*
存储在 MyClass
中并保留它直到 _StoredPtr
被取消后,但 _StoredPtr
decref 仍然存在段错误。 我尝试注释掉Py_DECREF(pAttr);
行,但这无济于事。
正如我所提到的,我可以使用_StoredPtr
检索PyClass
中的方法,并且我还尝试将它们存储在MyClass
中并在析构函数中取消引用。 当我这样做时,我可以 decref _StoredPtr
,但是当我尝试 decref 方法的PyObject*
时,它会出现段错误。 如果我使用多种方法执行此操作,则无论我将它们按什么顺序排列,导致段错误的始终是最后一个 decref。
关于这里发生的事情有什么见解吗?
我有用
#include <Python.h>
#include <iostream>
#include "MyClass.h"
MyClass::MyClass(const char* modulename) {
_StoredPtr = NULL;
PyObject *pName = NULL, *pModule = NULL, *pAttr = NULL;
// Import the Python module.
pName = PyString_FromString(modulename);
if (pName == NULL) {goto error;}
pModule = PyImport_Import(pName);
if (pModule == NULL) {goto error;}
// Create a PyClass instance and store a pointer to it.
pAttr = PyObject_GetAttrString(pModule, "PyClass");
if (pAttr == NULL) {goto error;}
_StoredPtr = (void*) PyObject_CallObject(pAttr, NULL);
Py_DECREF(pAttr);
if (_StoredPtr == NULL) {goto error;}
else{
// do something with _StoredPtr
Py_XDECREF((*PyObject)_StoredPtr)
}
error:
if (PyErr_Occurred()) {PyErr_Print();}
Py_XDECREF(pName);
Py_XDECREF(pModule);
return;
}
MyClass::~MyClass() {}
我基本上将 XDECREF 移到析构函数之外的函数中使用 PyObject 中。
- 编写代码时C++出现错误:错误 1 错误 C2601:'circle':本地函数定义是非法的
- 如何摆脱C ++中的分段错误错误?
- Clang 8 带有静态 constexpr 和数组的链接器错误 - 错误是什么以及如何解决它?
- 为什么每当我尝试运行此链接列表删除功能时都会收到分段错误错误?
- 如何解决分段错误错误C++
- 作为参数模板的模板类:MSVC 错误 - 错误 C2977:模板参数过多 (C++98)
- 安卓工作室 |CPP 文件错误错误: 位图库中对"AndroidBitmap_unlockPixels"的未定义引用
- 卷曲给出分段错误错误
- 无法访问 Arduino 结构字段。错误"退出状态 1。xxxx 不命名类型"
- 错误错误 C2872:"布尔值":kinect.h 的不明确符号
- C++打印模板容器错误(错误:"运算符<<"的不明确重载)理解?
- 结构的分割错误错误
- 为什么此代码返回分段错误错误?
- 错误错误:无法编译内置功能
- 分段错误错误C++
- C++ 1Z 错误:错误:演绎指南中声明中的显式限定
- 使用对数据类型的向量的哈希表中的分段错误错误
- 为什么此代码会导致分段错误错误
- JNA结构字段值错误
- C++段故障错误