4

特定の複雑なアプリケーションにlibsvmを使用しようとしていますが、libsvm はほとんどが C ライブラリであるため、特定のデータをロードした後、カスタム API 関数を使用してメモリを解放する必要があります。これが私が意味することです:

struct svm_model *model;
model = svm_load_model("path to model file");

//do some processing

svm_free_and_destroy_model(&this->model);

以下は、私が使用した libsvm API 関数の定義です。

struct svm_model *svm_load_model(const char *model_file_name);
void svm_free_and_destroy_model(struct svm_model **model_ptr_ptr);

これで問題なく動作しますが、モデル データの処理中に例外が発生すると、メモリ リークが発生します。これを防ぐために、上記のコードをクラスにラップsvm_load_modelし、コンストラクターとsvm_free_and_destroy_modelデストラクターで呼び出します。

さて、私たちはスマート ポインターの時代にいるので、もう少しクリエイティブになり、どうにかしてモデル変数を として宣言しstd::unique_ptr、ポインターをsvm_free_and_destroy_modelカスタム デロケーターとして設定することを考えていましたが、残念ながら、そうではありません。そのようなことが可能かどうかを判断することができます。現時点では、コンパイルすることさえできず、暗闇で撮影しているだけです。これが私がそれがうまくいくと思う方法です:

std::unique_ptr<struct svm_model *, /* what should I add here? */ > model (svm_load_model("path to model file"), svm_free_and_destroy_model);
4

2 に答える 2

5

への型引数はではなくstd::unique_ptrである必要があります。ラムダを使用して削除関数を呼び出します。TT *

std::unique_ptr<svm_model, void(*)(svm_model *)> 
  p( svm_load_model( "path_to_model" ), 
     []( svm_model *mdl ) { 
       svm_free_and_detroy_model( &mdl ); 
     } 
   );

VS2010 はステートレス ラムダから関数ポインターへの変換を実装していないため、これを機能させるには を使用する必要がありますstd::function

std::unique_ptr<svm_model, std::function<void(svm_model*)>>
  p( svm_load_model("path_to_model"), 
     []( svm_model *mdl ) {
       svm_free_and_destroy_model( &mdl );
     }
   );
于 2012-06-25T17:04:44.207 に答える
0

削除unique_ptr機能は、ポインターへのポインターではなく、ポインターのみを受け取る関数である必要があります。あなたは試すことができます:

void svm_deleter(svm_model*& model)
{
    svm_free_and_detroy_model(&model);
}

....

std::unique_ptr< svm_model, void(*)(svm_model*&) >(
    svm_load_model("path to model file")
  , &svm_deleter
);
于 2012-06-25T16:59:55.037 に答える