トップ 差分 一覧 ソース 検索 ヘルプ PDF RSS ログイン

Microsoft Visual C++ 6

[カテゴリ:言語]
[カテゴリ:VC6]

TRACE で出力が512バイトを超えるとassertのダイアログが表示される。これの回避方法。

原因は、dumpout.cpp で内部バッファが512バイトしか確保されていないからである。

TRACEで出力可能なのは半角512文字まで! (dinop.com)
http://www.dinop.com/vc/trace_512.html

ストリーム

std::cout = 標準出力

std::ostream とか。

マニュピレータとか。
'*'を10個出力してみる。

std::cout << setw(10) << setfill('*');
void func(std::ostream& os)
{
    os << "ABC";
}
std::ostream* os = new std::ofstream(filename, std::ios::out | std::ios::trunc);
:
delete os;

マニュピレータを自作する。

class CManu
{
private:
    int _val;
public:
    CManu(int val_) {
        this->_val = val_;
    };
public:
    std::ostream& operator()(std::ostream& os_) {
        os_ << (val_ + 1);
    };
};
std::ostream& operator <<(std::ostream& os_, CManu manu) {
    return manu(os_);
}

とすれば、

std::cout << "***" << CManu(1) << "***";


***2***

が出力される。

インスタンスを確実に破棄することを考える

まずは、基本から・・・

自動に破棄してくれるケース

ClassA obj();

自分で破棄するケース
new したら必ず delete

ClassA* obj = new ClassA();
delete obj;

次に、メソッドの戻りをクラスインスタンスにしたいとき。

class CSample
{
    CRet ClassA::method()
    {
        CRet ret();
        return ret;
    }
}

とすればよい。
インスタンスを返す。というのはそれなりにコストがかかる場合もあるかもしれない。

ということで、ちょっと発展させて・・・
ポインタで返すようにしてみる。

class CSample
{
    CRet* ClassA::method()
    {
        CRet* obj = new CRet();
        :
        return obj;
    }
}
CSample obj();
CRet* ret = obj.method();
:
delete ret;

deleteは、自分で必ず行う必要がある。
(忘れたらメモリリーク)
でもこれって案外忘れそう。。。

ということで、ちょっと発展させて・・・

先に作れるなら、コンストラクタで作っておき
メソッドではこれを返す。
デストラクタで開放する。

class CSample
{
    CRet* ret;
    CSample()
    {
        this->ret = new CRet();
    }
    ~CSample()
    {
        delete this->ret;
    }
    const CRet* ClassA::method()
    {
        return this->ret;
    }
}
CSample obj();
CRet* ret = obj.method();
:
//delete ret; これは不要

となる。
親でメモリ管理するので、
使う側はメモリ管理のことを忘れることができる。

プロファイル

プロファイル機能を使うにあたっての癖(?)をメモしておく。

1.
「プロジェクト → 設定 → リンク → 一般」の
「プロファイルを行う(E)」をチェックする。
ただし、VC側のバグで「プロファイルを行う(E)」をマウスでクリックしても
実際には「インクリメンタルリンクを行う(I)」をチェックしたことになる。
キーボードのEを押すことで選択する。
その他回避方法などは以下参照
http://katsura-kotonoha.sakura.ne.jp/prog/vc/tip00008.shtml

2.
「ビルド → プロファイル」の
「関数のタイミング(T)」をチェックして「OK」をクリックすると
各関数の実行回数や所要時間が表示される。

デバッグ実行とプロファイル実行で
以下の点が違っていた。

「プロジェクト → 設定 → デバッグ → 一般」の
「作業用のディレクトリ(W)」は無効になっていた。

GetModuleFileName()APIで取得する、実行ファイル名が
「xxx.exe」ではなく「xxx._xe」になっていた。

CMapが遅すぎる

処理させるデータ数によっては、CMapが遅くなる状況がある。
ハッシュテーブルのエントリ数なるものに
適切な値をセットすることで、かなり早くなる。

CMap::InitHashTable() のマニュアルより
http://msdn2.microsoft.com/ja-jp/library/w3yfk7a2(VS.80).aspx

パフォーマンスを最高にするには、ハッシュ テーブルのサイズを素数にします。
衝突を最小にするには、予想される最大のデータ セットよりも約 20% 大きいサイズにします。

ということで、

UINT hash_size = { (処理予定のデータ数 * 1.2) に近い素数 };
map.InitHashTable(hash_size);

するとよい。

最終更新時間:2009年01月12日 00時45分26秒