2

私は次のようなものを持っています

struct functor
{
  functor(){}
  virtual int operator()()=0;
};

struct impl : public functor
{
  int i;
  impl(int ii) : i(ii) {}
  virtual int operator()(){return i;};
};

void call(functor& f) {std::cout << f() << std::endl;}
class holder
{
public:
  holder(){}
  std::vector<functor*> dps;
};

class veer
{
public:
  std::vector<holder> hs;
  std::vector<impl> ds;
  veer(){}
  void add_h(int i)
  {
    ds.push_back(impl(i));
    holder th;
    th.dps.push_back(&ds.back()); //here
    hs.push_back(th);
  }
};
int main()
{
  veer v;
  v.add_h(10);
  v.add_h(9);
  for (auto ih: v.hs)   
    for (auto ifn : ih.dps)
    call(*ifn);
  return 0;
}

このセグメント障害。申し訳ありませんが、これ以上単純にすることはできません。これが最も単純で、実際のコードに最も近いものです。関数オブジェクトへのポインターのベクトルが必要です。私の推測では、マークされた行は//here無効なポインターを送信していますが、それ以外はまだこれを理解しようとしています。

4

1 に答える 1

2

問題はvector 、同じストレージを保持することが保証されていないことです:

new size() が capacity() より大きい場合、すべての反復子と参照 (末尾反復子を含む) が無効になります。それ以外の場合は、末尾イテレータのみが無効になります。

を呼び出すたびにadd_h、に保存したすべてのポインタが無効になる可能性がありますstd::vector<functor*>。物事のベクトルとそれらへのポインターのベクトルを同じ順序で持つユースケースは考えられません..これが本当に必要なものですか?

std::vector必要なスペースの順序で何かを使用する傾向があるため、ストレージを拡張する必要がある場合があります。内部では、新しい配列を作成し、既存の要素をコピーして、古い要素を削除する必要があります。それが行われると、古いポインタはすべてdeleteed メモリを指しています。

于 2014-05-30T18:28:10.437 に答える