2

OK、この質問はばかげているように聞こえるかもしれませんが、メモリ管理 (特に C/C++) は私の長所ではありませんでした。通常は目立たないので、見落としがちです。ですから、これがばかげているように聞こえる場合は、ご容赦ください。ただし、私の現在のプロジェクトには大量のデータと処理が含まれているため、メモリ消費量は数秒で簡単に 2GB を超えてしまい、全体が確実に遅くなるため、修正方法を考え始める時が来ました。


さて、私の状況ですが…

私のプリンシパルクラス(そのうち数百万のインスタンスを作成しています(使用されなくなるため、自動的に削除されることを願っています)。おそらくこれが原因です)は(大まかに)次のとおりです。

class MyClass
{
    public:
        // My Constructors
        MyClass ();
        MyClass (std::string param);

        // My Destructor (still empty)
        virtual ~MyClass ();

        // Some methods
        void methodA(std::string moves);
        void methodB();

        //----------------------
        // My Variables
        //----------------------
        boost::array<int,64> arrA;
        boost::array<unsigned int,13> arrB;
        unsigned int key;

        boost::array<int,3> arrC;       
        int argA;
        int argB;
};

そして、これは(大まかに-実際のコードは変更されています)上記のクラスのインスタンスがどのように作成されるかです:

vector<MyClass*> SomeOtherClass::getListOfObjects()
{   
    vector<MyClass*> objects;

    for (int i=0; i<MAX_OBJS; i++)
    {
          // Do some preparatory work
          objects += new MyClass();
    }

    return objects;
}

上記の関数の結果がどのように使用されているかを次に示します。

void SomeOtherClass::doSth()
{
    vector<MyClass*> objs = this->getListOfObjects();
    int objsSize = objs.size();

    for (int i=0; i<objsSize; i++)
    {
        MyClass* obj = objs[i];

        // Do sth with obj

        delete objs[i];
    }
}

だから、私の質問は:

  • オブジェクトが不要になったために解放されたときに、その「サブコンポーネント」もすべて解放されるように、デストラクタで何をすべきですか? (例: 2boost::array秒)

  • 上記のアプローチで何か問題がありますか?


私の実装について他に知っておくべきことがあれば教えてください...

4

4 に答える 4

5

クラス メンバーが動的に割り当てられているようには見えません。その場合delete、デストラクタで明示的に何もする必要はありません。この質問で、割り当てられたメモリへのポインタをいくつか省略した場合は、デストラクタでこれらを割り当てる必要newありますdelete

new必要な場合は、 -deleteと同様に覚えておいてください。への割り当ての場合を除きます。new[]delete[]std::unique_ptr

MyClassオブジェクト自体が でヒープに割り当てられている場合newは、それらを使用する必要がありdeleteます。

ps C++11 を使用している場合は、おそらくstd::array今すぐ使用する必要があります。


新しいコードから、から返されたリストを保持する人は誰でも、破棄するときに各要素getListOfObjects()を呼び出す必要があることは明らかです。deleteのデストラクタである可能性が高いですSomeOtherClass

または、ポインターをor (またはここで関連する可能性のあるブースト スマート ポインターのいずれか)MyClass*内にラップすることもできます。これは、ポインターを保持しているベクターがスコープ外になり、破棄されると自動的に削除されます。std::unique_ptrstd::shared_ptr


の表現が正確で、 get ddoSthのすべてのインスタンスが確実に実行される場合、このコードはメモリ リークの観点から問題ないように見えます。MyClassdelete

于 2013-01-21T07:36:59.640 に答える
3

私が見るのは、メモリを正しく管理するクラスだけです。プレーンな古い配列 (標準ライブラリ アルゴリズムのランダム アクセス読み取り専用コレクションにするためのメソッドが追加されているだけboost::arrayです) の派手なラッパーであり、オブジェクトの一部として割り当てられます。boost::array<int,64> arrAint arrA[64]

リークがあるとしたら、どこかでメモリの管理を誤っているようですが、それはここではありません。


最近の C++ では、delete を自分で書くことを避け、代わりに専用のデストラクタに任せる傾向にあります。上記の割り当てコードを考えると、Boost.Pointer Containerが適切なツールである可能性があります。

于 2013-01-21T07:42:33.383 に答える
1

これは少し奇妙に聞こえます

私のプリンシパルクラス(そのうち数百万のインスタンスを作成しています(使用されなくなるため、自動的に削除されることを願っています)

のインスタンスを作成MyClassしていて、何らかのスマート ポインターを使用してそれを行っていない場合、それらは魔法のように削除されないため、ジョブを実行する必要があります。

于 2013-01-21T07:54:39.740 に答える
1

私が見るものはすべてスタックに割り当てられています。そのため、それらは適切に管理され、デストラクタで適切に削除されています。メモリ リークがある場合は、呼び出しているnew MyClassが解放していない可能性があります。または他の場所で何か。

objects編集されたコードでわかるように、ベクトルがありますによって返され たアイテムを削除していますSomeOtherClass::getListOfObjectsか?

boost::shared_ptr<MyClass>生ポインタの代わりに使用することもできますMyClass*

于 2013-01-21T07:46:45.720 に答える