c++ - Python C API PyObject_Repr 段错误(核心转储)

标签 c++ segmentation-fault python-c-api

我正在尝试在我的 C++ 项目中使用 scikit learn。这是我正在使用的代码:

    #include <Python.h>
    PyObject* loadModule(char* name)//
    {
        PyObject* pName = PyString_FromString(name);
        PyObject* pModule = PyImport_Import(pName);
        Py_DECREF(pName);
        return pModule;
    }
    void displayPyObject(PyObject* object)
    {

    PyObject* objectsRepresentation = PyObject_Repr(object);
    PyErr_Print();
    const char* s = PyString_AsString(objectsRepresentation);
    PyErr_Print();
    std::cout << "[ PYOBJECT ]" << s << std::endl;

    }
    //load functions/ attributes from module
    PyObject* loadComponentFromModule(char* module, char* component) 
    {
       PyObject* pModule = loadModule(module);
       PyObject* pyComponent = PyObject_GetAttrString(pModule, component);
       Py_DECREF(pModule);
       return pyComponent;
    }


   //WRAPPER FOR KMEANS CLUSTERING FROM SCIKIT-LEARN
class KMeans
{
public:
    KMeans(int nClusters)
    {

        PyObject* KmeansClass = loadComponentFromModule("sklearn.cluster", "KMeans");
        PyObject* pName2 = PyInt_FromLong((long) nClusters);
        PyObject* pArgs = PyTuple_New(1);
        PyTuple_SetItem(pArgs, 0, pName2);
        _Kcluster = PyObject_CallObject(KmeansClass, pArgs);
        _closestor = loadComponentFromModule("sklearn.metrics","pairwise_distances_argmin_min");
        Py_DECREF(KmeansClass);
        Py_DECREF(pName2);
        Py_DECREF(pArgs);
    }
    ~KMeans()
    {
        Py_DECREF(_Kcluster);
       Py_DECREF(_closestor);
    }

    void setNumClusters(int nClusters)
    {
        std::cout << "change to number cluster: " << nClusters << "\n";
        PyObject* nCluster = PyInt_FromLong((long) nClusters);
        int code = PyObject_SetAttrString(_Kcluster,"n_clusters", nCluster);
        PyErr_Print();
        if (code == -1)
        {
            std::cout << "[Error] KMeans.setNumClusters() Failed!! - Number of clusters didn't change!!\n";
        }
        Py_DECREF(nCluster);
    }




    void info()
    {
        displayPyObject(_Kcluster);
    }

private:
    PyObject* _Kcluster;
    //PyObject* _result;
    PyObject* _closestor;
};

PyObject* loadClassifier()
{
    PyObject* loader = loadComponentFromModule("sklearn.externals.joblib", "load");
    PyObject* pName2 = PyString_FromString("lda.pkl");
    PyObject* pArgs = PyTuple_New(1);
    PyTuple_SetItem(pArgs, 0, pName2);
    PyObject* clf = PyObject_CallObject(loader, pArgs);
    Py_DECREF(loader);
    Py_DECREF(pName2);
    Py_DECREF(pArgs);
//    displayPyObject(clf);
    return clf;
}

void produce_error()
{
    std::cout << "============================= LINE 0 =========================================\n";
    PyObject* clf = loadClassifier();//"sklearn.externals.joblib", "load");
    std::cout << "============================= LINE 1 =========================================\n";
    KMeans cluster(8);
    std::cout << "============================= LINE 2 =========================================\n";
    cluster.setNumClusters(5);
    std::cout << "============================= LINE 3 =========================================\n";
    cluster.info();
    std::cout << "============================= LINE 4 =========================================\n";

}

int main(int argc, char *argv[])
{
    Py_Initialize();
    produce_error();
    Py_Finalize();
    return 0;
}

每次运行该程序时,都会收到错误:

============================= LINE 0 =========================================
============================= LINE 1 =========================================
Segmentation fault (core dumped)

据我了解,在不调用分类器的情况下,我不会收到任何错误,但每当我调用它(loadClassifier())并创建 KMeans 实例时,就会显示错误。有时错误出现在我加载模块的 KMeans 构造函数内部,在另一个函数中使用相同的代码(不在这里),错误出现在 PyObject_Repr() 内部(在 displayPyObject() 内部)。

有人遇到过同样的问题吗?你知道如何解决吗?提前致谢。

最佳答案

问题已解决。我想到了。因此,如果有人需要,请在这里回答。使用 Py_DECREF() 时要小心。问题来自 KMeans 构造函数中的这一行:

Py_DECREF(pName2);

因为当你运行 Py_DECREF(pArgs);它会尝试释放已经被释放的 pName2。它将产生不可预测的行为。评论该行后,一切运行正常。

关于c++ - Python C API PyObject_Repr 段错误(核心转储),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38508589/

相关文章:

python - 如何从 C 的 PyObject 类型的函数将值从 C 返回到 python?

c++ - 在哪里可以了解有关 C++0x 的更多信息?

c++ - 将 vector <vector<int>>作为平面数组访问

c - 追加到数组末尾

c - 段错误(核心转储)——如何修复我的代码?

python - 嵌入Python的C程序: How to restrict process to not open files nor sockets?

python - 在 Python C API 中使用多个模块/类型?

c++ - OpenGL VBO 不工作(C++)

c++ - 在 C++ 程序中创建连接

无法处理连续的 SIGSEGV 信号