0

push_back私は複雑な C++ コードをいくつか持っていますが、問題は構造のリストで実行することに絞り込まれます。

list<cache_page> cachedPages;

void f()
{
    cache_page cpage(a,b);
    cachedPages.push_back(cpage);
}

のすべてのデータ メンバーにコメントを付けましたがstruct cache_page、それでもエラーは解決しません。行をコメントしてpush_backもエラーはありません。

その理由は何ですか?

GDBを使用してみましたが、関数でエラーが発生し_List_Node_base::hook()ます。

template < class T >
class A
{
    T x;
    public:
        void func()
        {
          x->f();
        }

};

class B : public A < B* >
{
    list<cache_page> cachedPages;
    public:
        void f()
        {
            cache_page cpage;
            cachedPages.push_back(cpage);
        }
};

私は何もしないコピーコンストラクターを持っています。cache_page にデータ メンバーがありません。

4

7 に答える 7

7

あなたは小川を渡っています。ゴーストバスターズを見たことがない?小川を渡らないでください。

あなたはここで小川を渡っています:

class B : public A < B *>

私はこれのポイントを理解していません。あなたは何をしようとしているのですか?CRTP? これはそれが行われた方法ではありません。

問題はプッシュバックではなく、「これ」が無効であることです。

あなたが持っているとき

  void f()
  {
    cache_page cpage;
  }

NOPにコンパイルされます。これは承認されていません。すべて問題ありません。

  void f()
  {
    cache_page cpage;
    // oops this access
    this->cachedPages.push_back(cpage);
  }

A のコンテキストで呼び出されることを除いて。 this の値は何ですか? どこも初期化されていません。したがって、これは、初期化されていない幸せなリストが待機しているメモリ内にあるものと同じです。

修正?

template < class T >
class A
{
  T * _x;
public:
 explicit A(T * x) : _x(x) {}

 void func()
 {
   _x->f();
 }

};


class B : public A < B >
{
  list<cache_page> cachedPages;
public:
  B(void) : A<B>(this) {}

  void f()
  {
    cache_page cpage;
    cachedPages.push_back(cpage);
  }
};

これはうまくいくはずです。しかし、どうですか...

template < class T >
class A
{
public:
 void func()
 {
   static_cast<T>(this)->f();
 }

};


class B : public A<B>
{
  list<cache_page> cachedPages;
public:
  void f()
  {
    cache_page cpage;
    cachedPages.push_back(cpage);
  }

};

それがCRTPのやり方です。

于 2009-09-22T13:02:17.573 に答える
4

正しく思い出せば、すべてではないにしても一部のSTLコンテナーには、コピーコンストラクターと代入演算子が必要です。これら2つのデフォルトに依存している場合、または深いコピーを実行する必要があるときに浅いコピーを実行している場合は、それがセグメンテーション違反の原因である可能性があります。

于 2009-09-21T12:29:46.987 に答える
2

リストはcpageオブジェクトのコピーを実行していると思いますが、cpageがその状況でセグメンテーション違反を起こさない場合は、コピーコンストラクターを確認しましたか?

于 2009-09-21T12:27:20.503 に答える
1

cachedPages実際には存在しないように聞こえます。すでに削除されている可能性がありますか?

あるいは、f()はメンバー関数ですか?その(this)オブジェクトがまだ存在していることを確認しますか?メンバー関数内の多くの奇妙な外観の問題に戸惑いましたがprint *this、gdbだけで、次のスタックフレームで不正なポインターを参照解除したことに気付きました。

于 2009-09-21T12:30:41.030 に答える
1

二重削除している可能性があります。cpage のデストラクタはクリーンアップを行いますか? その場合、cpage に refcount を増やしたり、ディープ コピーを作成したりするコピー コンストラクターがない場合、クリーンアップが 2 回発生します。

于 2009-09-21T13:27:05.763 に答える
0

ソート ルーチンがリストのメンバーに新しい順序を割り当てることができるように、代入 (=) 演算子を指定する必要があります。その後は大丈夫だと思います。

于 2009-09-21T13:06:38.513 に答える
0

バグが見つかりました: それは本当に微妙なものです。コードでは、x はポインターであり、基本クラスで初期化されていません。x->f() を呼び出すと、vtable にアクセスして、派生クラス B の正しい関数を呼び出します。しかし、ポインター値が初期化されていないため、"this" パラメーターは間違っています。リストにアクセスしようとすると、無効な操作になり、コードがクラッシュします。

このエラーを修正するには、com の引数を constrof 型 T に渡します。これは、派生クラスのコンストラクターによってこれに初期化されます。

class A
{
public:
A(T p): x(p)
{
}

};

class B
{
public:
B() : A(this)
{
}
};
于 2009-09-22T07:44:40.330 に答える