【C++ STL バグ?】追試してくれる方を探しています。


Boostのshared_ptrのように参照カウントを行うスマートポインタに対し、それを格納する vector 配列を作成して stable_sort を実行すると参照カウントが狂ってしまいます。(sort なら大丈夫です)

サンプルコードをコメントに貼ります。

これは C++ Builder 5.0 の話なのですが、他の環境ではいかがでしょうか?また、これを回避する方法はないでしょうか?

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2007/03/02 16:59:26
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:Bookmarker No.2

回答回数191ベストアンサー獲得回数34

ポイント200pt

5.0 は手に入らなかったので、5.5 の STL を読んでみました。

memory.stl

template <class ForwardIterator>

_RWSTD_TRICKY_INLINE void __destroy (ForwardIterator first, ForwardIterator last);

がバグってる気がします。

  template <class ForwardIterator> 
  _RWSTD_TRICKY_INLINE void __destroy (ForwardIterator first, ForwardIterator last)
  {
    while (first != last)
      ++first;
  }

これを…

  template <class ForwardIterator> 
  _RWSTD_TRICKY_INLINE void __destroy (ForwardIterator first, ForwardIterator last)
  {
    while (first != last) {
      __RWSTD::__destroy(first);
      ++first;
    }
  }

こうすると直ると思います。

id:you1982

なるほど。デストラクタが呼ばれていないとは思ったのですが、呼んでいなかったのですね・・・。ちょっと試してみてまた結果を御報告します。どうもありがとうございます!

素晴らしい!やってみたところとりあえず上記の問題はうまく解決しました!取り急ぎ御報告まで。

<追記>

問題となっていたプログラム全体の動作にも問題なく、おかげさまで解決できました。本当にありがとうございました。

それにしてもRWのコードを眺めただけでよく分かりますね。あなたは神ですか!(笑)

2007/03/02 16:58:42

その他の回答1件)

id:Bookmarker No.1

回答回数191ベストアンサー獲得回数34

ポイント100pt

「g++ (GCC) 3.4.4 (cygming special) (gdc 0.12, using dmd 0.125)」+「boost-1.33.1」では、問題ありませんでした。

stable_sort 内でメモリーリークしているのかもしれませんね。

これを回避する方法はないでしょうか?

バグ(?)を直すか、STLport 等の C++ Builder 5.0 付属の STL 以外を使うとか…。

id:you1982

いつもありがとうございます!Builder 5.0付属のSTL(RW)の問題ですかねぇ。RWのvectorはいろいろバグが多くて困ります・・・。

ひとまず、上記の動作が異常だということが確認できて良かったです。今からSTLを入れ換えるのはそれはそれでリスキーなので、どうしたものか・・・orz

2007/03/02 10:50:34
id:Bookmarker No.2

回答回数191ベストアンサー獲得回数34ここでベストアンサー

ポイント200pt

5.0 は手に入らなかったので、5.5 の STL を読んでみました。

memory.stl

template <class ForwardIterator>

_RWSTD_TRICKY_INLINE void __destroy (ForwardIterator first, ForwardIterator last);

がバグってる気がします。

  template <class ForwardIterator> 
  _RWSTD_TRICKY_INLINE void __destroy (ForwardIterator first, ForwardIterator last)
  {
    while (first != last)
      ++first;
  }

これを…

  template <class ForwardIterator> 
  _RWSTD_TRICKY_INLINE void __destroy (ForwardIterator first, ForwardIterator last)
  {
    while (first != last) {
      __RWSTD::__destroy(first);
      ++first;
    }
  }

こうすると直ると思います。

id:you1982

なるほど。デストラクタが呼ばれていないとは思ったのですが、呼んでいなかったのですね・・・。ちょっと試してみてまた結果を御報告します。どうもありがとうございます!

素晴らしい!やってみたところとりあえず上記の問題はうまく解決しました!取り急ぎ御報告まで。

<追記>

問題となっていたプログラム全体の動作にも問題なく、おかげさまで解決できました。本当にありがとうございました。

それにしてもRWのコードを眺めただけでよく分かりますね。あなたは神ですか!(笑)

2007/03/02 16:58:42
  • id:you1982
    簡単なサンプルコードです。

    struct CFoo {
    };

    void test() {
    std::vector< shared_ptr<CFoo> > v;
    shared_ptr<CFoo> sp(new CFoo);
    v.push_back(sp);

    cerr << sp.use_count() << endl; // = 2
    stable_sort(v.begin(), v.end());
    cerr << sp.use_count() << endl; // = 3 に増えてしまう
    }

    上記ではBOOSTのshared_ptrを使っていますが、自作のスマートポインタでも問題が発生したので、参照カウント方式のスマートポインタならたぶん何でも問題が出そうです。

    stable_sort の中の copy を行ったタイミングで参照カウントが増えてるみたいなのですが、もう眠くて追えません・・・orz

    助けて、小人様!

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません