たとば、下記のようにMolの配列にSmiles文字列の配列をConvertしながら入れる場合、下記のコードはVisualStudioでは特に問題ありません。
(コードA)
for(i=0; i < 3; i++)
{
OBConversion conv = new OBConversion();
conv.SetInAndOutFormats("smi", "can");
conv.ReadString(obMol[i], obSmi[i]);
}
しかし下記のコードのように、CML文字列を変換する場合、実行中は何も問題ないのですが、終了するとメモリーエラーを起こします。
(コードB)
for(i=0; i < 3; i++)
{
OBConversion conv = new OBConversion();
conv.SetInAndOutFormats("cml", "can");
conv.ReadString(obMol[i], obCml[i]);
}
これは正しくは、こうするべきです。
(コードC)
for(i=0; i < 3; i++)
{
OBConversion conv = new OBConversion();
conv.SetInAndOutFormats("cml", "can");
conv.ReadString(obMol[i], obCml[i]);
conv.Dispose();
conv = null;
}
つまり、使用後のOBConversionインスタンスはちゃんと破棄する必要があります。このコードでは終了しても何もエラーがなく正常に動きます。
ただ不思議なのはコードAではメモリーエラーを起こさず、コードBではエラーを起こす点です。
想像するにCMLのConvertで何か内部的なメモリーの破棄忘れがあって、破棄しない場合にメモリーリークを起こしているではと思ってます。
さらにはコードCでもメモリーエラーを起こす場合があります。これはコードCを含む関数をdelegateで使う場合で、OBConversionのインスタンスが正常に破棄されず、ReadStringの箇所でメモリーエラーを起こします。
ということで、実用問題としてOpenBabelのCML変換は使えない、という結論に達しました。
これがわかるのに2日もかかりました。
ということでCML変換はCDKでやることにしました。その内容はまた別に書きます。
0 件のコメント:
コメントを投稿