2

newテンプレート化されたクラスのコンストラクターでキーワードを使用してメモリを割り当てると、非常に奇妙な動作が発生します。

テンプレート化されていないコードと比較すると、プログラムの実行は非常に遅くなります。

これを実証するために、バグを最小限に抑えたサンプル プログラムを作成しました。

using namespace std;

template<class tempT>
struct templatedClass{

    double* y;

    templatedClass() {
        y=new double[(int)1E6];
    }

    ~templatedClass() {
        delete y;
    }
};

class dummy {};

struct nontemplatedClass{

    double* y;

    nontemplatedClass() {
        y=new double[(int)1E6];
    }

    ~nontemplatedClass() {
        delete y;
    }
};

int main() {
    for(int c=0;c<4000;c++) {
        templatedClass<dummy>* A=new templatedClass<dummy>();
        //nontemplatedClass* A=new nontemplatedClass();
        delete A;
    }
    return(0);
}

これを g++ を使用してコンパイルします。私のコンパイラのバージョンは g++ (Debian 4.7.2-4) 4.7.2 です。

私が理解しているように、テンプレートはプログラム実行のパフォーマンスに大きな影響を与えるべきではありません。つまり、実行時に、テンプレート化されたクラスのコードは、テンプレートを使用していない特殊なクラスと異なるべきではありません。

また、注目すべき非常に興味深いのは、malloc代わりに使用する場合new、パフォーマンスの違いはなく、すべてがうまく機能することです。

結局のところ、これは g++ のバグのように思えます。

ps valgrind を使用しているときに、この動作がはるかに複雑なコードであることがわかりました。valgrindに一喝!

4

1 に答える 1

0

Zeta指摘したように、考えられる問題の 1 つは、 then を使用していることnewですdelete。これは、メモリ リークが発生している可能性があることを意味します。

で割り当てられたメモリと ... で割り当てられdeleteたメモリに使用する(正当な)推奨事項が見つかりますが、問題の真実は、または自分で呼び出すべきではなく、代わりにスマートポインターまたはコンテナーに依存してメモリの解放を処理することです。newdelete[]new[]deletedelete[]

あなたの場合、たとえばstd::vector<double>の代わりに使用する必要があります。double*

次に、Andy が言ったように、ベンチマーク最適化ビルド。そうでなければ無意味です。

于 2013-03-29T11:13:47.670 に答える