C++ C++;类对象的向量推回

C++ C++;类对象的向量推回,c++,object,vector,push-back,C++,Object,Vector,Push Back,我使用这个网站已经有一段时间了,到目前为止,我从来都不需要问一个新问题(找到了我需要的所有答案) 我需要将多个对象推回到一个向量中,但VS抛出了一个错误(这可能是由于堆损坏,这表明PVSS00DataGate.exe或它加载的任何DLL中存在错误),我似乎无法自行解决 这就是我要做的,它可以将第一个对象推回向量,但当我试图将第二个对象推回向量时,也就是错误发生的时候 class HWObject{} void DataLogger::WriteNewMessages() { unsigne

我使用这个网站已经有一段时间了,到目前为止,我从来都不需要问一个新问题(找到了我需要的所有答案)

我需要将多个对象推回到一个向量中,但VS抛出了一个错误(这可能是由于堆损坏,这表明PVSS00DataGate.exe或它加载的任何DLL中存在错误),我似乎无法自行解决

这就是我要做的,它可以将第一个对象推回向量,但当我试图将第二个对象推回向量时,也就是错误发生的时候

class HWObject{}

void DataLogger::WriteNewMessages()
{
  unsigned int iBattery = 0;
  unsigned int iSignal  = 0;
  TimeVar tTimeStamp;

  // I want to store all HWObjects in a temporary vector (loggerData)
  std::vector<HWObject> loggerData;

  CharString strElement;
  strElement.format( "batteryCondition.value" );
  SendOneValuePVSS( (const char *)strElement, iBattery,  tTimeStamp );

  strElement.format( "signalStrength.value" );
  SendOneValuePVSS( (const char *)strElement, iSignal,   tTimeStamp );
}

void DataLogger::SendOneValuePVSS(const char *szElementName, double dValue, TimeVar, &tValue)
{
  HWObject obj;
  obj.setOrgTime(tValue); // Current time
  obj.setTimeOfPeriphFlag();

  CharString address;
  address = strID;
  address += ".";
  address += szElementName;

  obj.setAddress(address);

  loggerData.reserve( loggerData.size() + 1 );
  loggerData.push_back( obj );
  obj.cutData();
}

你没有展示重要的部分。我猜
HWObject
已经 动态分配内存,不实现三个规则 (复制构造函数、赋值运算符和析构函数)。但这只是一个例子 猜测(除非您使用的是引用计数等特殊技术 或者智能指针,复制必须做深度复制,赋值应该 可能使用swap习惯用法。)

此外,在之前保留
size()+1也没有意义

向后推

你没有展示重要的部分。我猜
HWObject
已经 动态分配内存,不实现三个规则 (复制构造函数、赋值运算符和析构函数)。但这只是一个例子 猜测(除非您使用的是引用计数等特殊技术 或者智能指针,复制必须做深度复制,赋值应该 可能使用swap习惯用法。)

此外,在之前保留
size()+1也没有意义

向后推

这是如何编译的?您的
SendOneValuePVSS
函数不知道调用函数的本地
loggerData
向量?代码看起来很好,问题很可能出在
HWObject
类的定义中。我猜您正在将一个局部变量的地址存储在某个地方,该地址已变得无效。
HWObject
是否具有有效的复制构造函数和赋值运算符?需要知道您的对象
HWObject
是否具有复制构造函数,以及方法
setAddress
的工作方式。您应该真正提供一个可编译的这个编译的是testcase,而不是项目中可能遗漏了重要的pointsHow的随机行吗?您的
SendOneValuePVSS
函数不知道调用函数的本地
loggerData
向量?代码看起来很好,问题很可能出在
HWObject
类的定义中。我猜您正在将一个局部变量的地址存储在某个地方,该地址已变得无效。
HWObject
是否具有有效的复制构造函数和赋值运算符?需要知道您的对象
HWObject
是否具有复制构造函数,以及方法
setAddress
的工作方式。您应该真正提供一个可编译的测试用例,而不是项目中可能遗漏重要点的随机行。我认为你是对的。。HWObject类中没有导致vector push_back操作将指针复制到函数中声明的HWObject的复制构造函数,这似乎最终导致它超出范围。默认的复制构造函数将复制指针。这意味着,如果在析构函数中删除它,其他副本将留下一个悬空指针。如果你还没有读过Scott Meyers的《高效C++》,你应该——他详细介绍了这些类型的问题。我认为你是对的。。HWObject类中没有导致vector push_back操作将指针复制到函数中声明的HWObject的复制构造函数,这似乎最终导致它超出范围。默认的复制构造函数将复制指针。这意味着,如果在析构函数中删除它,其他副本将留下一个悬空指针。如果你还没有读过Scott Meyers的“高效C++”,你应该——他详细介绍了这些类型的问题。
class DataLogger 
{ 
 public:
 std::vector<HWObject> loggerData;
 ...
}
public:
   /** Default constructor*/
HWObject();

/** Constructor, which sets the periphAddr and transformationType.
 * @param addressString address of the HW object
 * @param trans type of transformation 
 */
HWObject(const char* addressString, TransformationType trans);

/**  Destructor. If the date pointer is not NULL, it is deleted.
 */ 
virtual ~HWObject();

/** Creates a new HWObject
 * This function returns an empty HWObject, no properties are duplicated or copied!
 * @classification public use, overload, call base
 */
virtual  HWObject * clone() const;

/** Reset all pvss2 relevant parts of the HWObject. when overloading this member
 * don't forget to call the basic function!
 * @classification public use, overload, call base
 */
virtual void               clear();

/** Gets pointer to data
 * @return pointer to data
 */
const PVSSchar *   getDataPtr() const                          { return dataPtr; }

/** Gets the data buffer pointer
 * @return data buffer pointer
 */
PVSSchar *         getData()                                   { return dataPtr; }

/** Cut the data buffer out of the HWObject.
 * This function is used to avoid the deletion
 * of the data buffer, when a new pointer is set using
 * setData() or the HWObject is deleted.
 * @return pointer to the data of the HWObject
 */
PVSSchar *         cutData();

/** Get the data buffer lenght
 * @return length of the data buffer
 */
PVSSushort           getDlen() const                             { return dataLen; }

/** Set ptr to the data buffer, pointer is captured.
 * The actual data pointer in the HWObject is deleted,
 * if it is not NULL. To avoid the deletion use cutData()
 * in order to cut out the pointer.
 * @param ptr pointer to new data
 */
void               setData(PVSSchar *ptr);

/** Set the data length
 * @param len length to be set
 */
void               setDlen(const PVSSushort len)                 { dataLen = len; }

/** Get the periph address
 * @return periph address string
 */
const CharString & getAddress() const                          { return address; }

/** Get the transformation type
 * @return type of transformation
*/
TransformationType getType() const                             { return transType; }

/** Set the transformation type
 * @param typ type of transformation for setting
 */
void               setType(const TransformationType typ)       { transType = typ; }

/** Get the subindex
 * @return subindex
 */
PVSSushort           getSubindex() const                         { return subindex; }

/** Set the subindex
 * @param sx subindex to be set
 */ 
void               setSubindex( const PVSSushort sx)             { subindex = sx; }

/** Get the origin time
  * @return origin time
  */
const TimeVar&     getOrgTime() const                          { return originTime; }

/** Get the origin time
 * @return oriin time
 */
TimeVar&           getOrgTime()                                { return originTime; }

/** Set the origin time
 * @param tm origin time to be set
 */
void               setOrgTime(const TimeVar& tm)               { originTime = tm; }

/** Get HWObject purpose
 * @return objSrcType
 */
ObjectSourceType   getObjSrcType() const                       { return objSrcType; }

/** Set HWObject purpose
 * @param tp objSrcType
 */
void               setObjSrcType(const ObjectSourceType tp)    { objSrcType = tp; }

/** Get number of elements in data buffer
 * @return number of elements in data buffer
 */
PVSSushort           getNumberOfElements() const                 { return number_of_elements; }

/** Set number of elements in data buffer
 * @param var number of elements in data buffer
 */
void               setNumberOfElements(const PVSSushort var)     { number_of_elements = var; }

/** Prints the basic HWObject information on stderr.
 * in case of overloading don't forget to call the base function!
 * @classification public use, overload, call base
 */
virtual void      debugPrint() const;

/** Prints th basic HWObject info in one CharString for internal debug DP.
  * in case of overloading call base function first, then append specific info 
  *  @classification public use, overload, call base 
   */
virtual CharString getInfo() const;

/** Set the periph address
  * @param adrStr pointer to address string
  */
virtual void       setAddress(const char *adrStr);

/** Set the additional data (flag, orig time, valid user byte,etc)
  * @param data aditional flags that be set
  * @param subix subindex, use subix 0 for setting values by default  
  */ 
virtual void       setAdditionalData(const RecVar &data, PVSSushort subix);

/** Set the 'origin time comes from periph' flag 
  */
void               setTimeOfPeriphFlag() 
{
  setSbit(DRV_TIME_OF_PERIPH);
}

/** Check whether time comes from periph
  * @return PVSS_TRUE if the time is from perip
  */
PVSSboolean        isTimeFromPeriph() const   
{
 // If isTimeOfPeriph is set, it must be valid
 return getSbit(DRV_TIME_OF_PERIPH);
}

/** Set the flag if you want to receive callback if event has answered the value change   
 */
void setWantAnswerFlag() 
{
  setSbit(DRV_WANT_ANSWER);
}

/** Get the status of the 'want answer, flag
  */
PVSSboolean        getWantAnswerFlag() const   
{
  // If isTimeOfPeriph is set, it must be valid
  return getSbit(DRV_WANT_ANSWER);
}

/** Set the user bit given by input parameter.
  * Status bits defined by the enum DriverBits
  * @param bitno bit number
  * @return PVSS_TRUE if bit was set
  */ 
PVSSboolean        setSbit(PVSSushort bitno)       
{
   return (status.set(bitno) && status.set(bitno + (PVSSushort)DRV_VALID_INVALID - (PVSSushort)DRV_INVALID));
}

/** Clear the user bit given by input parameter
  * @param bitno bit number
  * @return PVSS_TRUE if bit was cleared
  */ 
PVSSboolean        clearSbit(PVSSushort bitno)     
{
  return (status.clear(bitno) && status.set(bitno + (PVSSushort)DRV_VALID_INVALID - (PVSSushort)DRV_INVALID));
}

PVSSboolean        isValidSbit(PVSSushort bitno) const   
{
  return status.get(bitno + (PVSSushort)DRV_VALID_INVALID - (PVSSushort)DRV_INVALID);
}

/** Check any bit
  * @param bitno bit number
  * @return status of the bit on bitno position
  */
PVSSboolean        getSbit(PVSSushort bitno) const      {return status.get(bitno);}

/** Clear all status bits
  * return status of clear all
  */
PVSSboolean        clearStatus() {return status.clearAll();}

/** Get the status of this object
  * @return bit vector status
  */
const BitVec &     getStatus() const {return status;}

/** Set status of the bit vector
  * @param bv deference to bit vector to be set as status 
  */
 void               setStatus(const BitVec &bv) {status = bv;}

/** Set a user byte in the status.
  * @param userByteNo number of user byte range 0..3
  * @param val        value to set
  * @return PVSS_TRUE execution OK
  *         PVSS_FALSE in case of error
  */
PVSSboolean setUserByte (PVSSushort userByteNo, PVSSuchar val);

/** Reads a user byte from the status.
  * @param userByteNo number of user byte range 0..3
  * @return the requested user byte
  */
PVSSuchar getUserByte (PVSSushort userByteNo) const;

/** Check validity of user byte.
  * @param userByteNo number of user byte range 0..3
  * @return PVSS_TRUE user byte is valid
  *         PVSS_FALSE user byte is not valid
  */
PVSSboolean isValidUserByte(PVSSushort userByteNo) const;

/** Format status bits into a string
  * @param str status bits converted to string 
  */
void formatStatus (CharString & str) const ;
// ------------------------------------------------------------------
// internal ones

/** Read data from bin file
  * @param fp file handle 
  */
virtual int         inFromBinFile( FILE *fp );

/** Write data to bin file
  * @param fp file handle 
  */
virtual int       outToBinFile( FILE *fp );

/** Set data length
  * @param dlen  data length 
  */
void setDlenLlc (PVSSushort dlen) {dataLenLlc = dlen;}


virtual void updateBufferLlc (HWObject * hwo, int offset1 = 0);


virtual int compareLlc (HWObject * hwo, int offset1 = 0, int offset2 = 0, int len = -1);

/** Get dataLenLlc
* @return dataLenLlc
*/
PVSSushort getDlenLlc () const {return dataLenLlc;}

/** Function to delete the data buffer; overload if special deletion must be done
  */
virtual void deleteData ();

/** Set HW identifier
  * @param id hw identifier to be set
  */
void setHwoId(PVSSulong id) {hwoId = id;}

/** Get HW identifier
  * @return hw identifier
  */
PVSSulong getHwoId() const {return hwoId;}

protected:
/// the dynamic data buffer
PVSSchar*          dataPtr;
/// the data buffer len
PVSSushort           dataLen;
/// the pvss2 periph address string
CharString         address;
/// the start subix for the data buffer
PVSSushort           subindex;
/// the datatype of the data in the buffer (i.e. transformationtype)
TransformationType transType;
/// the time of income, normally set by the constructor
TimeVar            originTime;
/// the purpose of this HWObject
ObjectSourceType   objSrcType;
/// the number of elements in the data buffer, used for arrays and records
PVSSushort           number_of_elements;        // fuer array!!!
/// the user bits of the original config
BitVec             status;

private:
 PVSSushort dataLenLlc;
 PVSSulong hwoId;
};