0

問題のコードは次のとおりです。

ヘッダ:


  class Vec3d : public Object {
    public:
      static linearalgebra::Vec3d* X_AXIS;
      static linearalgebra::Vec3d* Y_AXIS;
      static linearalgebra::Vec3d* Z_AXIS;
      static linearalgebra::Vec3d* AXES[3];

      static int f();
  };

実装:

  Vec3d* Vec3d::X_AXIS = new Vec3d();
  Vec3d* Vec3d::Y_AXIS = new Vec3d();
  Vec3d* Vec3d::Z_AXIS = new Vec3d();
  Vec3d* Vec3d::AXES[3] = {Vec3d::X_AXIS, new Vec3d(),Vec3d::Z_AXIS};

int Vec3d::f() { X_AXIS = AXES[2]; }

これらのnew()演算子を使用せずに、新しいヘルパー変数を追加しない方法はありますか?

プログラムの他の部分と互換性を持たせるには、型はそのままである必要があります。

編集:答えから推測すると、ヘルパー変数が使用されていない場合は、new()を使用する必要があります。それは本当ですか?したがって、ヘルパー変数を追加する場合があります。これはとにかくコンパイラによって生成されたコードなので、ヘッダーが読み取り可能である限り問題ありません。

次は大丈夫でしょうか?現在、Valgrindはリークはないと言っています。


  static Vec3d INIT_X_AXIS;
  static Vec3d INIT_Y_AXIS;
  static Vec3d INIT_Z_AXIS;
  static Vec3d INIT_AXES_1;

  Vec3d* Vec3d::X_AXIS = &INIT_X_AXIS;
  Vec3d* Vec3d::Y_AXIS = &INIT_Y_AXIS;
  Vec3d* Vec3d::Z_AXIS = &INIT_Z_AXIS;
  Vec3d* Vec3d::AXES[3] = {Vec3d::X_AXIS, &INIT_AXES_1, Vec3d::Z_AXIS};
4

7 に答える 7

1

これらのポインタが解放されない場合、C ++で問題ありませんか?

「OK」を定義します。あなたのプログラムは機能しますか?はい。それは良い考えですか?いいえ!

私には、これを使用したほうがよいように思われます。

class Vec3d : public Object {
public:
    static linearalgebra::Vec3d xAxisMemory;
    static linearalgebra::Vec3d yAxisMemory;
    static linearalgebra::Vec3d zAxisMemory;
    static linearalgebra::Vec3d axesMemory[3];

    static linearalgebra::Vec3d* X_AXIS;
    static linearalgebra::Vec3d* Y_AXIS;
    static linearalgebra::Vec3d* Z_AXIS;
    static linearalgebra::Vec3d* AXES[3];

    static int f();
};


Vec3d Vec3d::xAxisMemory;
Vec3d Vec3d::xAxisMemory;
Vec3d Vec3d::xAxisMemory;
Vec3d Vec3d::axesMemory[3];

Vec3d* Vec3d::X_AXIS = &xAxisMemory;
Vec3d* Vec3d::Y_AXIS = &yAxisMemory;
Vec3d* Vec3d::Z_AXIS = &zAxisMemory;
Vec3d* Vec3d::AXES[3] = {&axesMemory[0], &axesMemory[1], &axesMemory[2]};
于 2011-07-08T09:32:04.523 に答える
1

そのようなものをすべて保持したい場合は、それを行うことができます(これは良い設計ではありませんが、機能するはずです)。私は構築しようとしませんでしたが、大丈夫なはずです。

Vec3d* Vec3d::X_AXIS = NULL;
Vec3d* Vec3d::Y_AXIS = NULL;
Vec3d* Vec3d::Z_AXIS = NULL;
Vec3d* Vec3d::AXES[3] = { 0 };

namespace {
    const struct Initializer {
        Initializer() {
            static Vec3d x, y, z;
            AXES[0] = X_AXIS = &x;
            AXES[1] = Y_AXIS = &y;
            AXES[2] = Z_AXIS = &z;
        }
    } Init;
}
于 2011-07-08T09:32:39.487 に答える
1

それらは割り当てられているので、出口で漏れています。Vec3dで静的メソッドを作成して、シャットダウン時にメモリを破棄できます(プログラムが終了する前に呼び出します)。

于 2011-07-08T09:24:39.560 に答える
1

取得されたが戻されなかったメモリリソースは、メモリリークと見なされます。したがって、new()callnigによって割り当てられたメモリを解放しない限り、を使用して動的メモリを取得した場合delete()、メモリリークが発生します。

あなたが持っているオプションは何ですか?

プログラムを終了する前に、これらの各リソースでdeleteを呼び出して、割り当てられたメモリの割り当てを明示的に解除する静的メソッドを使用できます。

より良い代替案は次のとおりです。生のポインターの代わりにスマートポインター
の 使用を検討する必要があります。スマートポインタを使用する場合スマートポインタを使用した後は、明示的に 呼び出す必要はありません。それらの静的タイプへの参照が残っていない場合、それらは暗黙的に削除されます。このようにして、各リソース自体が割り当て解除を処理します。
delete

于 2011-07-08T09:25:57.870 に答える
0

その後、メモリの割り当てを解除しないnewと、メモリリークが発生します。あなたはしなければなりませんdelete/delete[]

newforの使用を禁止する場合Vec3dは、それらprivateを作成して実装しないでください。

class Vec3d {
private:
  void* operator new (std::size_t); // don't implement it
public:
//...
};

このように、コンパイラはでの使用new()を許可しませんVec3d。また、自動ストレージでこの変数を作成することも考えられます。それらをポインタとしてではなく、オブジェクトとして宣言するだけです。

static linearalgebra::Vec3d X_AXIS;
于 2011-07-08T09:23:37.720 に答える
0
  1. スマートポインタを使用して自動メモリ割り当て解除を処理する

  2. 静的関数を追加してメモリの割り当てを解除し、「atexit」に登録します

于 2011-07-08T09:25:06.363 に答える
0

メモリリークです。newで割り当てられた変数は、deleteキーワードで削除する必要があります。

参照カウンターとして機能する別の静的変数を作成してみることができます。コンストラクタでは+1を追加し、デストラクタでは-1を追加します。マイナス1を実行した後のデストラクタで、変数が0であるかどうかを確認し、0である場合は、静的メンバーに対してdeleteを呼び出します。

ヘッダ:

static int  _refCount;

実装:

int Vec3d::_refCount = 0;

Vec3d::Vec3d()
{
    _refCount += 1;
}

virtual Vec3d::~Vec3d()
{
    _refCount -= 1;
    if (_refCount == 0)
    {
        //delete all allocated memory in static variables
    }
}

..または、スマートポインタの実装を使用することもできます。

于 2011-07-08T09:26:51.053 に答える