アトリエ ぺっぺ

トップページ > プログラムTips > vectorの使用方法

◆ vectorの使用方法
vectorは動的な配列を扱うとき、非常に便利ですが、モノが配列なだけあって、間違った使い方をすると多くのメモリを無駄遣いしてしまいます。

例えば、あるvectorがあって、その中から条件に一致するものを抜き出して参照する場合、こんなことをしていませんか?
    class AAA;
    
    void FindHoge(const vector<AAA>& vcSrc, vector<AAA>& vcRet){
        int nCount((int)vcSrc.size());
        for(int i = 0; i < nCount; i++){
            if(vcSrc[i].hoge == 1){
                vcRet.push_back(vcSrc[i]);
            }
        }
    }
これを見て、はて、どこがまずいんだろう?と思った方。
順番に見ていきましょう。

まず、この関数は、vcSrcのなかから、メンバhogeが1であるものを集めて返す、という機能であるのは分かると思います。
そして、hoge==1を見つけたら、そのままvcRetにつっこんでますね。

これをしてしまうと、vcSrc[i]のインスタンスが丸々コピーされてしまいます。
これは同じものが2つある、つまりメモリの無駄遣いになっているということが分かるでしょうか。

もし返した先でvcRetの内容を参照するだけならば、次のように書くべきです。
    class AAA;
    
    void FindHoge(const vector<AAA>& vcSrc, vector<AAA*>& vpcRet){
        int nCount((int)vcSrc.size());
        for(int i = 0; i < nCount; i++){
            if(vcSrc[i].hoge == 1){
                vpcRet.push_back(&vcSrc[i]);
            }
        }
    }
こうすることで、インスタンスが丸々コピーされることを防げます。
また無駄なコピーを防げるということは、クラスAAAのコンストラクタが呼ばれなくなるので、高速かも望めます。
さらに、ポインタのvectorになったおかげで、push_backにかかる時間も短縮されます。

既にあるものに対する選別にvectorを使う場合、もし内容が参照されるだけならば、必ず実体ではなくポインタを格納するようにしましょう。