0

背景: IBM ILOG Cplex の C++ インターフェースは、型にはまらない方法でメモリーの割り当てと割り当て解除を行います。

ILO 環境を宣言し、IloEnv environment;この環境内でモデルとソルバーを構築し、これらすべてのオブジェクト (環境を含む) をスコープ外に出すと、メモリ リークが発生します。new演算子を使用していないことに注意してください。これを回避する 1 つの方法はenvironment.end();、オブジェクトがスコープ外になる前に呼び出すことです。

設定:現在、特定の ILP を解決することを目的としたクラスがあります。このクラスにはいくつかのメンバー変数があります。

IloEnv ilpEnvironment_;
IloObjective ilpObjective_;
IloExpr ilpExpression_;
IloModel ilpModel_;
IloCplex ilpSolver_;
IloNumArray ilpSolution_;
IloNumVarArray ilpVariables_;
IloNumArray ilpStartValues_;
IloRangeArray constraints_; 

これらのメンバー変数は、コンストラクターの初期化リストで初期化されます。

inline MyClass::MyClass() 
:   ilpEnvironment_(),
    ilpObjective_(ilpEnvironment_),
    ilpExpression_(ilpEnvironment_),
    ilpModel_(ilpEnvironment_),
    ilpSolver_(ilpModel_),
    ilpSolution_(ilpEnvironment_),
    ilpVariables_(ilpEnvironment_),
    ilpStartValues_(ilpEnvironment_),
    constraints_(ilpEnvironment_)
{ /* ... */ }

デストラクタは、すべてのメモリ (メンバー変数を操作するクラスのメンバー関数によって割り当てられた) の割り当てを解除します。

inline MyClass::~MyClass() {
    ilpEnvironment_.end();
}

質問:void clear()メモリの割り当てを解除し、クラスを初期状態に戻すメンバー関数を実装するにはどうすればよいですか? これは、私が行った、うまくいかない2つのかなり単純な試みです。

inline void MyClass::clear() {
    ilpEnvironment_.end();
    ilpEnvironment_ = IloEnv(); // does not work, whether or not I comment this line out
    ilpObjective_ = IloObjective(ilpEnvironment_);
    ilpExpression_ = IloExpr(ilpEnvironment_);
    ilpModel_ = IloModel(ilpEnvironment_);
    ilpSolver_ = IloCplex(ilpEnvironment_);
    ilpSolution_ = IloNumArray(ilpEnvironment_);
    ilpVariables_ = IloNumVarArray(ilpEnvironment_);
    ilpStartValues_ = IloNumArray(ilpEnvironment_);
    constraints_ = IloRangeArray(ilpEnvironment_);
}
4

1 に答える 1

2

クラスの目的が特定の ILP モデルを解決することである場合、モデル サイズ/パラメーターでクラスを初期化し、solve() メンバー関数内で CPLEX オブジェクトを作成および破棄し、結果のみをクラス メンバーとして保存します。クラス メンバーはモデル パラメータになり、オブジェクトはすべての CPLEX 取引を隠します。

その特定の solve() 呼び出しでアクティブにする制約を追跡するクラス メンバーを持つこともできます。

CPLEX オブジェクトを変更可能なクラス メンバーとして絶対に使用する必要がある場合、オブジェクト自体ではなく、オブジェクト ポインターをクラス メンバーとして使用することをお勧めします。IloEnv::end() を呼び出すと、関連付けられているオブジェクトが破棄されるため、IloEnd::end() を呼び出してから、ポインターを新しいオブジェクトに再割り当てできます。

于 2013-07-21T14:00:55.077 に答える