2016-07-21 2 views
2

내 C++ 프로젝트에서 scikit learn을 사용하려고합니다.Python C API PyObject_Repr 분할 오류 (코어 덤프)

#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() 내부).

누구나 전에 동일한 문제가 발생합니까? 그것을 해결하는 방법을 알고 있습니까? 미리 감사드립니다.

답변

2

문제가 해결되었습니다. 나는 그것을 알아. 누군가가 필요하면 미래에 대한 대답을하십시오. Py_DECREF()를 사용할 때 충분합니다. 이 문제는 KMeans의 생성자 내부에있는이 행에서 가져옵니다.

Py_DECREF(pName2);

Py_DECREF (pArgs); 이미 해제 된 pName2를 해제하려고 시도합니다. 그것은 예측할 수없는 행동을 일으킬 것입니다. 그 줄을 주석 처리하고 난 후, 모든 것이 잘 돌아갑니다.