3

奇妙な問題があります。オブジェクトを次のようにプッシュしたいベクトルがあります。

vector<DEMData>* dems = new vector<DEMData>();
DEMData* demData = new DEMData();
// Build DEMDATA

dems->push_back(*demData);

ベクトルには数百の DEMData オブジェクトがあります。問題は、このコードが終了したとき、すべてのアイテムがベクターに「プッシュバック」された最後のアイテムと等しいことです。

ベクトルで他のオブジェクトがオーバーライドされるのはなぜですか?

編集:

DemData クラスは単純で、セッターとゲッターを含むデータ構造だけです。

    class DEMData
{
private:
    int bitFldPos;
    int bytFldPos;
    const char* byteOrder;
    const char* desS;
    const char* engUnit;
    const char* oTag;
    const char* valType;
    int index;
public:
    void SetIndex(int index);
    int GetIndex() const;
    void SetValType(const char* valType);
    const char* GetValType() const;
    void SetOTag(const char* oTag);
    const char* GetOTag() const;
    void SetEngUnit(const char* engUnit);
    const char* GetEngUnit() const;
    void SetDesS(const char* desS);
    const char* GetDesS() const;
    void SetByteOrder(const char* byteOrder);
    const char* GetByteOrder() const;
    void SetBytFldPos(int bytFldPos);
    int GetBytFldPos() const;
    void SetBitFldPos(int bitFldPos);
    int GetBitFldPos() const;
    friend std::ostream &operator<<(std::ostream &stream, DEMData d);
};

編集:

XML ファイルを読み取り、各 xml 要素の属性に基づいて DEMData オブジェクトを構築しています。

DEMData demData;
  for (i = 0; attr[i]; i += 2)
  {
      if(strcmp(attr[i],"BitFldPos") == 0)
      {
      demData.SetBitFldPos(*attr[i + 1] - '0');
      }
      else if(strcmp(attr[i],"BytFldPos") == 0)
      {
        char* pEnd;
        int tmp = strtol(attr[i + 1],&pEnd,10);
        demData.SetBytFldPos(tmp);
      }
      else if(strcmp(attr[i],"ByteOrder") == 0)
      {
        demData.SetByteOrder(attr[i + 1]);
      }
      else if(strcmp(attr[i],"DesS") == 0)
      {
      demData.SetDesS(attr[i + 1]);
      }
      else if(strcmp(attr[i],"EngUnit") == 0)
      {
        demData.SetEngUnit(attr[i + 1]);
      }
      else if(strcmp(attr[i],"OTag") == 0)
      {
        demData.SetOTag(attr[i + 1]);
      }
      else if(strcmp(attr[i],"ValTyp") == 0)
      {
        demData.SetValType(attr[i + 1]);
      }
      else if(strcmp(attr[i],"idx") == 0)
      {
        char* pEnd;
        int tmp = strtol(attr[i + 1],&pEnd,10);
        demData.SetIndex(tmp);
      }
      //printf(" %s='%s'", attr[i], attr[i + 1]);
  }


  // Insert the data in the vector.
  dems.push_back(demData);
4

5 に答える 5

6

ベクターを new で割り当てるのはなぜですか? DEMData一時オブジェクトを新しいものに割り当てるのはなぜですか?

Aは、そのデータ自体ではなく、渡されたもののコピーvectorを格納するため、new で割り当てた DEMData オブジェクトを削除しない限り、アイテムをベクターにプッシュするたびにメモリ リークが発生します。同様に、ベクトルを動的に割り当てることで、メモリ リークの問題に備えることができます。

ベクトル内のオブジェクトがすべて同じデータを含んでいるように見える理由については、同じデータが多く含まれている可能性がかなり高いです。おそらく、ポインターを誤ったコピー ctor と組み合わせて使用​​し、本来あるべきいくつかの場所で浅いコピーを実行してしまう可能性があります。 't -- しかし、そのコードを見せていないので、それは推測にすぎません。

編集: DEMData クラスのコードを追加したので、上記の推測が正しかったように見えます。ポインターがあり、ユーザー定義のコピー ctor がないため、浅いコピーを取得しています。

最初のステップとして、すべてのポインター char メンバーを取り除き、それらをstd::strings に置き換えます。intメンバーは問題ないはずです。メンバーをコピーすると、値がコピーされます。

Edit2:これらのメンバー変数で何をしているのかを考えると、変数用と変数std::map用の 2 つの sを使用することを検討する必要があるように見えます。std::stringint

于 2010-02-22T21:17:02.223 に答える
3

ベクトルはオブジェクトへの参照ではなく、そのコピーを保持することに注意してください。これは、新しく作成された のインスタンスをDEMDataベクターに格納してオブジェクトを更新した後、ベクター内の対応するエントリが更新されないことを意味します。

DEMData*指す値ではなく、ベクトルストアとpush_backポインターを作成する必要があります。

于 2010-02-22T21:16:02.483 に答える
1

オブジェクトの文字列は同じだと思います。おそらく、同じ demData オブジェクトを使用してベクトルを設定します。

また、デフォルトのコピー コンストラクターを使用するため、すべてのコピーには同じ (char*) ポインターが含まれます。これらのポインタが参照するメモリの内容を変更すると、すべてのコピーがその変更を認識します。

于 2010-02-22T21:24:08.803 に答える
0

文字列のメモリを管理するには、クラスにコピー コンストラクタとデストラクタDEMDataが必要です。現状では、(おそらく) 起こっていることは、オブジェクトが作成され、同じポインター値を持つ のDEMData新しいインスタンスを作成するベクターに挿入されることです。DEMData次に、DEMData(デストラクタがないため) オリジナルを破棄し、ポインタをベクトルにぶら下げたままにします。次に、新しいDEMDataものを作成すると、(偶然に) 同じメモリ ロケーションが取得され、最終的にすべてのオブジェクトが同じロケーションを指します。

于 2010-02-22T21:19:54.800 に答える
-2

この場合、ベクター自体と関係があるかどうかはわかりません...ベクターへのポインターを使用し、demData(スタックにポインターを割り当てる代わりに) 少し疑わしいようです。

通常の C++ コードは次のようになると思います。

vector<DEMData>* dems = new vector<DEMData>();
DEMData demData
// Build DEMDATA

dems->push_back(demData);
...
delete dems;

残りのコードを貼り付けていただけますか? それとも、demData の構築を行うループでしょうか?

于 2010-02-22T21:15:42.673 に答える