MFCのバグ発見

使うと結構便利なMFCにもやはりバグは存在します。
これは案外危険で気が付かないうちに使ったりしています。
アプリケーションが思い通りに動かず、幾ら自分の書いたソースを検証しても
デバッグをしても原因が全く分からないなんて事になりかねません。
それもそのはず。原因はライブラリに有るのですから。
デバッグで胃に穴があくほどボロボロになってから
ライブラリにバグが有ったことを知るのでは遅いのです。

と言う訳でいくつか発見したバグとその解決方法を紹介します。
(VC++6.0 SP2で確認。それ以上のバージョンでは解決されている可能性が有ります。)

CString::Delete()

この関数はCString型文字列から文字列を削除します。
MDSNには以下のように書かれています。

> int Delete( int nIndex, int nCount = 1 )
> throw( CMemoryException );
>
> nIndex 位置の文字またはこの文字以降の複数の文字を削除します。
> nCount を文字列の長さより大きい値にすると、
> 指定位置以降の文字列全体が削除されます。

しかし実際は nIndex + nCount の文字数が文字列の長さを超えると
文字列は削除されず、実行時にエラーが発生します。
これを回避するにはDelete()を呼び出す前に文字数などをチェックし
削除する文字数を減らして nIndex + nCount が文字列の長さを超えないようにします。


int nCount;
int nIndex;
CString str;

      :

// CString::Delete()バグ回避
int nLength = str.GetLength();
if(nIndex < nLength)
{
    if(nIndex + nCount > nLength)
        nCount = nLength - nIndex;

    str.Delete(nIndex, nCount);
}


CFileFind::GetFilePath()

この関数はFindFile()で検索した指定のファイルのフルパスを返す関数です。
しかしFindFile()の引数でディレクトリ名の最後が"表"や"ソ"等の
S-JISコードで'\'を含む文字を使用すると最後の'\'が抜けたパスを返します。
つまり例えば本来なら"c:\表\tmp.txt"と返す所が"c:\表temp.txt"と返すわけです。

解決方法のアルゴリズムは以下の通りです。

・ファイルのフルパスを取得。
・返されたフルパスからファイル名のみを削除。
・ファイル名を削除した文字列から'\'を後方検索。
・検索で取得された位置が文字列の一番後ろの位置かチェック。
・一番最後が'\'でなければフルパスに'\'を追加する。


CFileFind fnd;

      :

// CFileFind::GetFilePath()バグ回避
CString strPath = fnd.GetFilePath();

CString strTmp = strPath.Left(strPath.GetLength() - fnd.GetFileName().GetLength());
if(strTmp.GetLength() != strTmp.ReverseFind('\\') + 1)
    strPath.Insert(strTmp.GetLength(), '\\');

< 戻る << HOME ©1999-2001 by Akky, All right reserved.