C++ vector push_back mit class-Objekt
Ich habe mit dieser Website für eine Weile und bisher noch nie benötigt, um eine neue Frage (fand alle Antworten, die ich brauchte bis jetzt).
Muss ich push_back mehrere Objekte in einen Vektor, aber VS wirft einen Fehler (Dies kann durch eine Korruption des heap-gibt einen bug in PVSS00DataGate.exe oder eine der DLLs geladen), ich kann nicht scheinen zu funktionieren für mich.
Hier ist, was ich versuche zu tun, es funktioniert, um push_back das erste Objekt in den vector, aber wenn ich versuche push_back ein zweites Objekt, das ist, wenn der Fehler Auftritt.
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();
}
Datenlogger deklariert ist
class DataLogger
{
public:
std::vector<HWObject> loggerData;
...
}
Hier wird die Klasse HWObject, ich wollte Sie nicht überwältigen Sie mit 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;
};
SendOneValuePVSS
Funktion ist nicht bekannt, der lokalen loggerData
Vektor der aufrufenden Funktion?Der code sieht gut aus, das problem ist wahrscheinlich in der definition der
HWObject
Klasse. Ich nehme an, du bist zum speichern einer Adresse einer lokalen Variablen, die irgendwo die ungültig wird.Tut
HWObject
haben eine gültige Kopie-Konstruktor und Zuweisungsoperator?Müssen wissen, ob Ihr Objekt
HWObject
hat einen copy-Konstruktor und auch, wie die Methode setAddress
funktioniert.Sollten Sie wirklich ein echtes kompilierbare testcase statt zufällige Linien aus dem Projekt, dass wohl die wichtigsten Punkte
InformationsquelleAutor Jonathan Rojas Garcia | 2011-09-22
Du musst angemeldet sein, um einen Kommentar abzugeben.
Du bist nicht die die wichtigsten Teile. Ich denke, dass
HWObject
hatdynamisch allozierten Speicher, und nicht implementieren Sie die Regel der drei
(copy-Konstruktor, Zuweisungs-operator und Destruktor). Aber es ist nur eine
erraten. (Es sei denn, Sie verwenden spezielle Techniken, wie die Verweiszählung
oder smart pointers, kopieren Sie tun müssen, eine Tiefe Kopie, und die Zuordnung sollte
wahrscheinlich verwenden die swap-idiom.)
Auch, es gibt keinen Punkt in der Reservierung
size() + 1
kurz vorpush_back
.Der Standard-copy-Konstruktor kopiert die Zeiger. Das bedeutet, dass, wenn Sie es löschen, einen Destruktor, der andere kopiert werden Links mit einem baumelnden Zeiger. Wenn Sie noch nicht gelesen Scott Meyers' "effective C++", sollten Sie---er deckt diese Arten von Problemen im detail.
InformationsquelleAutor James Kanze