2016-07-21 8 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を解放しようとします。予期しない動作が発生します。その行をコメントした後、すべてが正常に実行されます。

関連する問題