开发者

C++ vector push_back with class object

I've been using this site for a while and so far never needed to ask a new question (found all answers I've needed until now).

I need to push_back multiple objects into a vector but VS throws an error (This may be due to a corruption of the heap, which indicates a bug in PVSS00DataGate.exe or any of the DLLs it has loaded) that I cannot seem to work out for myself.

Here is what I am trying to do, it works to push_back the first object into the vector but when I try to push_back a second object that is when the error occurs.

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();
}

dataLogger is declared in

class DataLogger 
{ 
 public:
 std::vector<HWObject> loggerData;
 ...
}

Here is the class HWObject, I didn't want to overwhelm you with code.

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;
};


You're not showing the important parts. I'd guess that HWObject has dynamically allocated memory, and doesn't implement the rule of three (copy constructor, assignment operator and destructor). But it's only a guess. (Unless you're using special techniques like reference counting or smart pointers, copy must do a deep copy, and assignment should probably use the swap idiom.)

Also, there's no point in reserving size() + 1 just before push_back.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜