1
class SomeData{};
typedef boost::shared_ptr<SomeData> data_ptr;

class ABC {
public:   ABC(){}

          ~ABC(){cached_ptr.reset(); }

          data_ptr get_ptr() {data_ptr x; return x;} // it does work and returns a data_ptr

          bool someWork(data_ptr& passed_ptr) {
            if(cached_ptr == NULL) {
              cached_ptr = get_ptr();
              passed_ptr.reset(new SomeData(*cached_ptr));
            }
            return true;
          }

          data_ptr otherWork() {
            if(cached_ptr == NULL) { 
                cached_ptr = get_ptr();
                data_ptr local_ptr = boost::make_shared<SomeData>(*cached_ptr);
            }
            return data_ptr;   // after some more work
         }

private:  data_ptr cached_ptr;   // class member
};

上記は、私が作業しようとしているいくつかのコードを簡略化したものです。

「cached_ptr」を追加するまでは、毎回 get_ptr() を呼び出さないように、連続する呼び出し間でデータをキャッシュする機能がありました (かなり大きくなる可能性があります)。

注: 私は boost::make_shared と reset() を持っています - エラーがコピーによって引き起こされたかどうかを確認するために両方を試しました。違いはありませんでした(予想どおり)。

既に Google テストの単体テストを実施しています。cached_ptr を追加すると、Google テストで「GTEST_HAS_SEH」のようなエラーが発生しました。

"unknown file: error: SEH exception with code 0xc000005 thrown in the test body."

エラーはデストラクタで発生します: cached_ptr.reset();

Visual Studio は次のように述べています。

    "First-chance exception at 0x00ceba41 in myFile_gtest.exe: 0xC0000005: 
Access violation reading location 0xfeeefeee."

それがなくても発生します(最初はreset()さえ配置していませんでした。共有ポインターはスコープを超えると自分自身を殺すと思いました。

私の問題は何ですか?

ブースト1.47

ありがとうございました。

4

3 に答える 3

0

Andy Prowl が (私の質問へのコメントで) 気付いたように、ポインターが指しているクラスにはコピー コンストラクターが含まれていませんでした。

boost::make_shared には、コピーを作成するためにコピー コンストラクターが必要です...

存在しない場合は同じデータを指していたため、元のポインターが範囲外になると、キャッシュされたポインターはそのポイントを失いました (ただし、デバッグ時には、まだポインターが残っているように見えました...)

SomeData問題を解決するためのコピーコンストラクターを追加しました。

于 2013-05-07T22:29:51.580 に答える
0
typedef boost::shared_ptr<SomeData> data_ptr;

data_ptr get_ptr() { data_ptr x; return x; }

  cached_ptr = get_ptr();
  passed_ptr.reset(new SomeData(*cached_ptr));

get_ptr()ポインターを返したNULL後、それを逆参照しました。

cached_ptr以外に設定することはありませんNULLが、それは別の問題です。

于 2013-05-07T19:53:42.300 に答える
0

次のフラグメントで null ポインター (*cached_ptr) を逆参照します。

cached_ptr = get_ptr();
passed_ptr.reset(new SomeData(*cached_ptr));

そのため、プログラムは整形式になりません。この場合、期待することはできません。

于 2013-05-07T19:54:03.557 に答える