2011-09-22 70 views
1

我一直在使用這個網站一段時間,迄今沒有必要問一個新的問題(找到我需要的所有答案,直到現在)。C++矢量push_back與類對象

我需要將多個對象push_back到一個向量中,但是VS會拋出一個錯誤(這可能是由於堆的損壞,這表明PVSS00DataGate.exe或它已經加載的任何DLL的錯誤),我不能似乎爲我自己工作。

這是我想要做的,它的作品push_back第一個對象到矢量,但是當我嘗試push_back錯誤發生時的第二個對象。

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

數據記錄器在

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

這裏聲明是類HWObject,我不想用代碼來壓倒你。

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

這是如何編譯的?你的'SendOneValuePVSS'函數不知道來自調用函數的本地'loggerData'向量? – Nim

+0

代碼看起來很好,問題很可能在'HWObject'類的定義中。我猜你正在存儲一個局部變量的地址變成無效。 –

+1

'HWObject'是否有一個有效的拷貝構造函數和賦值操作符? – minjang

回答

1

您沒有顯示重要部分。我猜HWObject有 動態分配內存,並沒有實現三個規則 (複製構造函數,賦值運算符和析構函數)。但這只是一個 的猜測。 (除非你使用類似引用計數 或智能指針特殊的技術,副本必須做一個深拷貝和分配應 可能使用交換成語。)

此外,還有在保留size() + 1沒有點只是 push_back前。

+0

我認爲你是對的..在HWObject類中沒有複製構造函數,它導致向量push_back操作將指針複製到函數中聲明的HWObject,看起來這會導致它最終超出範圍。 –

+0

默認的複製構造函數將複製指針。這意味着如果您在析構函數中刪除它,其他副本將留下一個懸掛指針。如果您還沒有閱讀Scott Meyers的「Effective C++」,那麼您應該詳細講述這些類型的問題。 –