3

我有一个奇怪的问题。我有一个向量,我想将对象推到这样的位置:

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

dems->push_back(*demData);

向量中将有几百个 DEMData 对象。问题是当这段代码完成时,所有项目都等于最后一项“推回”到向量吗?

为什么向量中的其他对象被覆盖?

编辑:

DemData 类很简单,只是一个带有 setter 和 getter 的数据结构:

    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 分配向量?你为什么用 new 分配你的临时DEMData对象?

Avector存储您传递给它的内容的副本,而不是数据本身,因此除非您删除使用 new 分配的 DEMData 对象,否则每次将项目推送到向量时都会泄漏内存。同样,您正在通过动态分配向量来解决内存泄漏问题。

至于为什么向量中的对象似乎都包含相同的数据,很有可能你有更多相同的数据——可能使用指针和不正确的复制 ctor 最终在它应该做的几个地方做浅拷贝't - 但由于您没有向我们展示该代码,这只是一个猜测。

编辑:现在您已经为 DEMData 类添加了代码,看起来很像上面的猜测是正确的——您有指针并且没有用户定义的复制 ctor,所以您得到的是浅拷贝。

作为第一步,我将删除所有指针 char 成员,并将它们替换为std::strings。int成员应该没问题 - 复制它们将复制值。

Edit2:鉴于您对这些成员变量所做的事情,看起来您应该考虑使用两个std::maps - 一个用于std::string变量,一个用于int变量。

于 2010-02-22T21:17:02.223 回答
3

请注意,您的向量不包含对对象的引用,而是它们的副本。这意味着在您将新创建的实例存储DEMData在向量中并更新对象后,向量中的相应条目将不会更新。

你需要让你的向量 storeDEMData*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 回答