Changing a private member variable does not affect the whole class - c++

I have a class, in it is a private member variable called which is an int. For some reason, if I change its value in a method (on the constructor, for example), it will change just fine. But if I change it on a different method and use printf to output what its contents are on yet another different method, the value is not carried over and is changed into a very very large number.
Header:
class Fruit {
private:
int m_fruitState; // 0 = IDLE, 1 = GROWING, 2 = READY, 3 = FALLEN, 4 = ROTTEN
int m_fruitTimer;
public:
Fruit ( );
int getFruitState( ); // Returns m_fruitState
void setFruitState( int fState );
void growFruit( CCTime dt ); // Called every 1 second (CCTime is a cocos2d-x class)
};
CPP
#include "Fruit.h"
Fruit::Fruit( ) {
// Set other member variables
this -> setFruitState( 0 ); // m_fruitState = 0
this -> m_fruitTimer = 0;
this -> m_fruitSprite -> schedule( schedule_selector( Fruit::growFruit ), 1.0 ); // m_fruitSprite is a CCSprite (a cocos2d-x class). This basically calls growFruit() every 1 second
}
int getFruitState( ) {
return this -> m_fruitState;
}
void setFruitState( int state ) {
this -> m_fruitState = state;
}
void growFruit( CCTime dt ) {
this -> m_fruitTimer++;
printf( "%d seconds have elapsed.", m_fruitTimer );
printf( "STATE = %d", this -> m_fruitState ); // Says my m_fruitState is a very big number
// This if condition never becomes true, because at this point, m_fruitState = a very big number
if ( this -> getfruitState( ) == 0 ) { // I even changed this to m_fruitState == 0, still the same
if ( this -> m_fruitTimer == 5 ) { // check if 5 seconds have elapsed
this -> setFruitState( 1 );
this -> m_fruitTimer = 0;
}
}
}
And then on the main, I make an instance of MyClass.
I have no idea why that happens. Why does C++ do that and how do I fix it?
Thanks in advance.

The "selector" argument to schedule should be a SEL_SCHEDULE, where
typedef void(CCObject::* SEL_SCHEDULE)(float)
i.e it should be a member function of a CCObject.
It is also supposed to be a member of the object you call schedule on, otherwise the target when it's called will be wrong.
I suspect that this
this -> m_fruitSprite -> schedule( schedule_selector( Fruit::growFruit ), 1.0 );
causes a call to Fruit::growFruit with this pointing at the sprite, not the fruit, which leads to all kinds of unpleasantness.
(Note that schedule_selector does a C-style cast, which means that it's inherently unsafe. Don't use it.)

changeInt( int newInt ); // Assume newInt = 5
Remove the int from the above line.
void doSomething( ); {
Remove the ; from the above line.
Update: Now you're missing a ; from the end of the header file. Fixing all the obvious bugs (that would likely keep it from even compiling), it works fine for me. Either there's still a difference between the code you pasted and the real code, or you've found a compiler bug.
Constructor: myInt = 0
changeInt( int ) : myInt = 5
After constructor and calling changeInt(), myInt = 5

Related

std::map pass by reference Pointer to Object

I'm coding a plugin for XPLANE10 which gets a MSG from ROS.
My IDE is QTcreator 4.1.0 based QT 5.7.0 for Ubuntu 64 Bit. I would like to use C++11 Standards
My code explained
The main initializes ROS and creates a map -> container.
ROS spins in a loop till my GUI sends a MSG where my AirPlane should fly.
The MSG contains 3 floats(phi, theta, psi) where "phi" is the AirPlane ID, theta contains the ID for my ETA(Estimated Time of Arrival)
and psi contains the ID for my pose All of the IDs are saved in the ParameterServer(lookuptable).
So at the beginning i look up the activeAirplanes which returns a vector . I would like to store them in a map where the key is the AirCraft ID and the second param is an instance of the Object.
So i have initialized the for example(looked in container while debugging):
[0] first = 1 // Airplane ID1
[0] second = new CObject(freq)
[1] first = 2 // Airplane ID2
[1] second = new CObject(freq)
If i get a MSG from GUI
phi = 1
theta=2
psi=3
,
ROS will callback
MSG(....std::map<i32, CObject> &container)
// if phi is 1 so use the mapkey 1 and trigger the method do_stuff from CObject
do_stuff(phi, theta, psi,freq)
I would like to call the in a function from main
int getPlanes(std::map<i32,CObject>& container)
{
...
getActiveAirplanesFromServer(activePlanes);
}
First Question:
How do i pass the container to my callback?
Second Question:
How do i parallelize do_stuff() so my callback will return to main and i'm able to command more aircrafts while the others are calculated?
Third Question:
How would be the correct syntax for getPlanes to pass the container by reference so getPlanes() can edit it?
Fourth Question:
Is there a difference between
std::map<i32,CObject*> map
std::map<i32,CObject>* map
and
std::map<i32,CObject*>::iterator it=container->begin();
std::map<i32,CObject*>::iterator* it=container->begin();
If yes, what do i want ? #4Solved
// I have to edit stuff 'cause of some restrictions in my company.
#include "Header.h"
int main()
{
f64 freq = 10;
std::map<i32, CObject>* container;
std::map<i32,CObject>::iterator* it=container->begin();
// ROS
if(!ros::isInitialized())
{
int rosargc = 0;
char** rosargv = NULL;
ros::init(rosargc, rosargv, "MainNode");//), ros::init_options::AnonymousName);
}
else
{
printf("Ros has already been initialized.....\n");
}
ros::NodeHandle* mainNodeHandle=new ros::NodeHandle;
ros::AsyncSpinner spinner(2);
ParameterServer * ptrParam= new ParameterServer(mainNodeHandle);
ros::Subscriber airSub=mainNodeHandle->subscribe<own_msgs::ownStruct>("/MSG",
1000,
boost::bind(MSG,
_1,
freq,
container));
std::vector<i32> activePlanes;
i32 retVal=0;
retVal += ptrParam-> ParameterServer::getActiveAirplanesFromServer(activePlanes);
if (retVal == 0 && activePlanes.size()>0)
{
for (u32 j =0; j <activePlanes.size(); j++)
{
container->insert (std::pair<i32,CObject> (activePlanes[j] , new CObject(freq)));
}
}
while (ros::ok())
{
spinner.start(); //spinnt sehr viel :-)
ros::waitForShutdown ();
}
std::cout<<"ENDE"<<std::endl;
int retval = 1;
return retval;
}
void MSG(const own_msgs::ownStruct<std::allocator<void> >::ConstPtr &guiMSG,
f64 freq,
std::map<i32, CObject> &container)
{
if ((guiMSG->phi != 0) && (guiMSG->theta != 0) && (guiMSG->psi != 0))
{
std::string alpha = std::to_string(guiMSG->phi)+std::to_string(guiMSG->theta)+to_string(guiMSG->psi);
container.at(guiMSG->phi) -> do_stuff(guiMSG->phi,guiMSG->theta,guiMSG->psi, freq);
}
else
{
std::cout<<" Did not receive anything\n"<<endl;
}
}
void do_stuff(...)
{
//copy the IDs to private Member of this single Object
//setROS() for this single Object
//callback the current AC pose via ID from XPLANE
//callback the wished AC pose via ID from ParamServer
// do some calculations for optimum flight path
// publish the Route to XPlane
}
EDIT::
Problem is i get it to compile now and if debug it and set a breakpoint at :
void MSG(const own_msgs::ownStruct<std::allocator<void> >::ConstPtr &guiMSG,f64 freq,std::map<i32, CObject*> &container)
{
..
/*->*/ container.at(guiMSG->)...
}
The Container remains empty.
So i read some stuff about pointers and i saw my errors..
I confused * and &
if i want to pass the adress of a variable i have to write like
int main()
{
int a = 0;
AddTwo(&a)
cout<<a<<endl; // Output: 2
}
void AddTwo(int* a)
{
a+=2;
}

How do I cast a void pointer to a int[3]?

I need to call a 3rd party library and pass in an int[3] as a void * like this [works]:
int pattern[3] = {2,4,10};
if ( OSTaskCreate( BlinkLED,
( void * ) pattern,
( void * ) &BlinkTaskStack[USER_TASK_STK_SIZE],
( void * ) BlinkTaskStack,
MAIN_PRIO - 1 ) != OS_NO_ERR )
{
iprintf( "*** Error creating blink task\r\n" );
}
But now I need to parse a string to get the pattern array and I can't seem to get it right.
First I pass the string into the parser and get back the array:
int (&ParseBlinkOnCommand(char rxbuffer[3]))[3]
{
// Code parses rxbuffer and creates the 3 ints needed
int pattern[3] = {repeats, onTicks, offTicks};
return pattern;
}
Then I try to pass it to the OSTaskCreate just like I did before:
int pattern2[3] = ParseBlinkOnCommand(rxbuffer);
if ( OSTaskCreate( BlinkLED,
( void * ) pattern2,
( void * ) &BlinkTaskStack[USER_TASK_STK_SIZE],
( void * ) BlinkTaskStack,
MAIN_PRIO - 1 ) != OS_NO_ERR )
{
iprintf( "*** Error creating remote blink task\r\n" );
}
but I get the error 'array must be initialized with a brace-enclosed initializer'.
What is the right way to do this?
First, ParseBlinkOnCommand returns reference to local object and so return dangling reference.
Second C-array are not copyable, so int pattern2[3] = ParseBlinkOnCommand(rxbuffer); should be int (&pattern2)[3] = ParseBlinkOnCommand(rxbuffer);.
but why not using std::vector or std::array (or custom structure) ?
std::vector<int> ParseBlinkOnCommand(const char (&rxbuffer)[3])
{
// Code parses rxbuffer and creates the 3 ints needed
return {repeats, onTicks, offTicks};
}
And then
auto pattern2 = ParseBlinkOnCommand(rxbuffer);
if ( OSTaskCreate( BlinkLED,
pattern2.data(),
&BlinkTaskStack[USER_TASK_STK_SIZE],
BlinkTaskStack,
MAIN_PRIO - 1 ) != OS_NO_ERR )
{
iprintf( "*** Error creating remote blink task\r\n" );
}

Memory Corruption Due to Copy Constructor/Deleting Array?

I have a struct called SFrame which contains many elements, notably 2 elements which are of type unsigned char*. I create a member variable of this struct in my class but I newly initialize it on each iteration in a function in my class (except for when a certain boolean is true). I do this in the following manner:
if (false == m_bRemainderNeedsProcessing)
{
// ... calls before and after the initialization are unimportant and not shown
m_sFrame = SFrame();
}
Then I pass m_sFrame to a function to assign some of its elements and then I need to assign an unsigned char array to my pszMessage variable in my struct.
m_sFrame.iMessageSize = m_sFrame.iPayloadLength;
m_sFrame.iOriginalMessageSize = m_sFrame.iPayloadLength;
m_sFrame.pszMessage = new unsigned char[m_sFrame.iPayloadLength + Constants::RSSL_DECODE_PADDING];
m_sFrame.pszOriginalMessage = new unsigned char[m_sFrame.iPayloadLength + Constants::RSSL_DECODE_PADDING];
These SFrame instances are stored in a vector of SFrames i.e.
std::vector<SFrame>;
I want to be able to reuse m_sFrame for each iteration but I have to ensure that if I am going to clear the contents of the SFrame, that when I store it inside the vector, the SFrame is copied into the vector without losing it's assigned values. For this I create a copy constructor for SFrame:
I have attached an image of part of the SFrame's copy constructor.
At the end of my function, I clear the memory in the pszMessage (and the pszOriginalMessage which is almost the same) by doing the following:
ClearMemory(m_sFrame.pszMessage);
Where the ClearMemory function does the following:
void CPCAPParser::ClearMemory(unsigned char *pszBuffer)
{
if(pszBuffer != NULL)
{
delete [] pszBuffer;
}
}
Thee problem is, this function seems to be deleting more than it should do.... because after many iterations, I get an unhandled exception: Access Violation...
I've attached a few images that might help convey what the problem is. Really need help with this :(, if anyone needs me to add more details let me know.
Thanks
http://imageshack.com/f/pduGDLGZp (Constants::RSSL_DECODE_PADDING has length 7 so there are 13 bytes in total which have been set - made evident at the start of the memory block).
http://imageshack.com/f/exRaaEmip - Where I am calling ClearMemory (the memory address is obviously still the same).
I would post more images but I don't have enough rep...
SFrame:
struct SFrame
{
int* ipTemp_int_ptr;
int* ipTemp_int_ptr_actual;
int* piTimestampPos;
int* piOffset;
int iIP_Header_Length;
int iTCP_Header_Length;
int iTCP_Source_Port;
int iTCP_Dest_Port;
long long uiSequenceNumber;
long long uiInitialSequenceNumber;
long long uiAckNumber;
int iIp_total_length;
int iActual_frame_length;
int iOriginal_frame_length;
int iCaptured_frame_length;
int iTotalPayloadLength;
int iTotalMsgLoad;
int iPayloadLength;
int iBytesComplete;
int iFragmentID;
int iRemainder;
int iMessageSize;
int iOriginalMessageSize;
long long iNextExpectedSequenceNum;
std::string strSourceAddress;
std::string strDestAddress;
std::string strTimestamp;
unsigned char* pszMessage;
unsigned char* pszOriginalMessage;
unsigned int uiClientID;
int iStartOfRemainder;
int iAccumulatedMsgLength;
SFrame() : ipTemp_int_ptr ( NULL ),
ipTemp_int_ptr_actual ( NULL ),
piTimestampPos ( NULL ),
piOffset ( NULL ),
pszMessage ( NULL ),
pszOriginalMessage ( NULL ),
iIP_Header_Length( 0 ),
iTCP_Header_Length ( 0 ),
iTCP_Source_Port ( 0 ),
iTCP_Dest_Port ( 0 ),
iIp_total_length ( 0 ),
iActual_frame_length ( 0 ),
iOriginal_frame_length ( 0 ),
iCaptured_frame_length ( 0 ),
uiSequenceNumber( 0 ),
uiInitialSequenceNumber ( 0 ),
uiAckNumber( 0 ),
iPayloadLength ( 0 ),
iNextExpectedSequenceNum ( 0 ),
uiClientID ( 0 ),
iMessageSize ( 0 ),
iOriginalMessageSize ( 0 ),
iFragmentID( 0 ),
iTotalPayloadLength( 0 ),
iBytesComplete( 0 ),
iAccumulatedMsgLength ( 0 ),
iRemainder ( 0 ),
iStartOfRemainder( 0 ),
iTotalMsgLoad ( 0 )
{
}
SFrame(const SFrame &c_rSrc)
{
*this = c_rSrc;
}
SFrame &SFrame::operator=(const SFrame &c_rSrc)
{
iIP_Header_Length = c_rSrc.iIP_Header_Length;
iTCP_Header_Length = c_rSrc.iTCP_Header_Length;
iTCP_Source_Port = c_rSrc.iTCP_Source_Port;
iTCP_Dest_Port = c_rSrc.iTCP_Dest_Port;
iIp_total_length = c_rSrc.iIp_total_length;
iActual_frame_length = c_rSrc.iActual_frame_length;
iOriginal_frame_length = c_rSrc.iOriginal_frame_length;
iCaptured_frame_length = c_rSrc.iCaptured_frame_length;
iPayloadLength = c_rSrc.iPayloadLength;
uiSequenceNumber = c_rSrc.uiSequenceNumber;
uiInitialSequenceNumber = c_rSrc.uiInitialSequenceNumber;
uiAckNumber = c_rSrc.uiAckNumber;
iNextExpectedSequenceNum = c_rSrc.iNextExpectedSequenceNum;
uiClientID = c_rSrc.uiClientID;
iFragmentID = c_rSrc.iFragmentID;
iMessageSize = c_rSrc.iMessageSize;
iOriginalMessageSize = c_rSrc.iOriginalMessageSize;
iTotalPayloadLength = c_rSrc.iTotalPayloadLength;
iBytesComplete = c_rSrc.iBytesComplete;
iAccumulatedMsgLength = c_rSrc.iAccumulatedMsgLength;
iRemainder = c_rSrc.iRemainder;
iStartOfRemainder = c_rSrc.iStartOfRemainder;
iTotalMsgLoad = c_rSrc.iTotalMsgLoad;
strSourceAddress = c_rSrc.strSourceAddress;
strDestAddress = c_rSrc.strDestAddress;
strTimestamp = c_rSrc.strTimestamp;
pszMessage = (c_rSrc.pszMessage == NULL) ? NULL : new unsigned char[c_rSrc.iMessageSize];
pszOriginalMessage = (c_rSrc.pszOriginalMessage == NULL) ? NULL : new unsigned char[c_rSrc.iOriginalMessageSize];
if(pszMessage != NULL)
{
memcpy(pszMessage, c_rSrc.pszMessage, c_rSrc.iMessageSize);
}
if(pszOriginalMessage != NULL)
{
memcpy(pszOriginalMessage, c_rSrc.pszOriginalMessage, c_rSrc.iOriginalMessageSize);
}
return *this;
}
~SFrame()
{
delete [] pszMessage;
delete [] pszOriginalMessage;
}
};
Your problem is that your SFrame struct is not safely asignable, yet you are placing instances of this in a std::vector that will make copies.
Either:
Add a working user-defined copy constructor and assignment operator to your SFrame struct or
Replace the pointer members with std::vector.
You have many members in your struct now. If you miss just one in your copy constructor, or your handling of allocated memory is faulty, you will have a broken copy. Since a vector<SFrame> will create copies, having broken copies is a no-go with vector<SFrame>.
So instead of this, here is the fix using option 2:
#include <vector>
struct SFrame
{
std::vector<int> ipTemp_int_ptr;
std::vector<int> ipTemp_int_ptr_actual;
std::vector<int> piTimestampPos;
std::vector<int> piOffset;
int iIP_Header_Length;
int iTCP_Header_Length;
int iTCP_Source_Port;
int iTCP_Dest_Port;
long long uiSequenceNumber;
long long uiInitialSequenceNumber;
long long uiAckNumber;
int iIp_total_length;
int iActual_frame_length;
int iOriginal_frame_length;
int iCaptured_frame_length;
int iTotalPayloadLength;
int iTotalMsgLoad;
int iPayloadLength;
int iBytesComplete;
int iFragmentID;
int iRemainder;
int iMessageSize;
int iOriginalMessageSize;
long long iNextExpectedSequenceNum;
std::string strSourceAddress;
std::string strDestAddress;
std::string strTimestamp;
std::vector<unsigned char> pszMessage;
std::vector<unsigned char> pszOriginalMessage;
unsigned int uiClientID;
int iStartOfRemainder;
int iAccumulatedMsgLength;
SFrame() :
iIP_Header_Length( 0 ),
iTCP_Header_Length ( 0 ),
iTCP_Source_Port ( 0 ),
iTCP_Dest_Port ( 0 ),
iIp_total_length ( 0 ),
iActual_frame_length ( 0 ),
iOriginal_frame_length ( 0 ),
iCaptured_frame_length ( 0 ),
uiSequenceNumber( 0 ),
uiInitialSequenceNumber ( 0 ),
uiAckNumber( 0 ),
iPayloadLength ( 0 ),
iNextExpectedSequenceNum ( 0 ),
uiClientID ( 0 ),
iMessageSize ( 0 ),
iOriginalMessageSize ( 0 ),
iFragmentID( 0 ),
iTotalPayloadLength( 0 ),
iBytesComplete( 0 ),
iAccumulatedMsgLength ( 0 ),
iRemainder ( 0 ),
iStartOfRemainder( 0 ),
iTotalMsgLoad ( 0 )
{
}
};
Note that the copy constructor and assignment operator (and destructor) are now gone, thus making the code a lot easier to handle, as well as not having a chance of missing any of the members during the copy. Instead we let the compiler generate the copy, and the compiler will always get every member copied.
Now, your code base that uses the struct has to be recompiled, and you will inevitably get compiler errors. However those errors are usually very easy to fix. Most will probably require you to
Remove the lines with delete [] somepointer; where somePointer is now a vector and
If passing a pointer to the beginning of the buffer, you pass &vector[0] or vector.data(), since a vector is basically a wrapper for new[]/delete[].
Going back to your original code, one issue with your assignment operator is that you failed to delete the previous memory allocated, thus you have a memory leak. Also, you didn't check for self-assignment, given the way you wrote the copy operations. However, this may not have been the only error, as we didn't see how you're using these SFrame instances.
Therefore it may be better to change to vector, fix the compiler errors, rebuild and test your app.

Maya API - Move CV with Kinect

I’m trying to create a 64-bit plug-in for Autodesk Maya 2013. The aim of this plug-in is to be able to model objects through the Kinect.
In context, with the plug-in you can select the CV of a created object. To specify you want to move the selected points, the position of selected CV is updated constantly.
Here is my problem, when I try to update the position of a selected CV of an object, the result is not displayed on the screen.
I have tried many ways without getting any result, as an example:
1) when I do the setPosition the point doesn’t update.
for ( ; !iter.isDone(); iter.next() ) {
iter.getDagPath( mdagPath, mComponent );
MItSurfaceCV sCvFn( mdagPath, mComponent, true, &stat );
if ( MS::kSuccess == stat ) {
for ( ; !sCvFn.isDone(); sCvFn.nextRow() ) {
for ( ; !sCvFn.isRowDone(); sCvFn.next() ) {
MPoint pto(pHand.posX, pHand.posY, pHand.posZ);
sCvFn.setPosition(pto, MSpace::kWorld);
}
}
}
sCvFn.updateSurface();
}
2) in this case, if you iterate over the array newCVS before doing the setCVs you can see the updated points.
But then, when doing setCVs and looking for the position in the CV array of the object (doing a getCVs) the position of the modified CV doesn’t change.
for ( ; !iter.isDone(); iter.next() ) {
stat = iter.getDagPath( mdagPath, mComponent );
if(stat == MS::kSuccess) {
MFnNurbsSurface surf(mdagPath);
MItSurfaceCV sCvFn( mdagPath, mComponent, true, &stat );
MPointArray currentCV;
surf.getCVs(currentCV, MSpace::kWorld);
MPointArray newCVS(currentCV.length(), MPoint::origin);
newCVS.setLength(currentCV.length());
for(unsigned i = 0; i < currentCV.length(); i++){
newCVS[i] = newCVS[i] + currentCV[i];
}
int index;
if ( MS::kSuccess == stat ) {
for ( ; !sCvFn.isDone(); sCvFn.nextRow() ) {
for ( ; !sCvFn.isRowDone(); sCvFn.next() ) {
sCvFn.getIndex(indexU, indexV);
int posArray = indexU * surf.numCVsInV() + indexV;
index = posArray;
MVector diff = MPoint(pHand.posX, pHand.posY, pHand.posZ) - currentCV[posArray];
newCVS[posArray] = newCVS[posArray] + diff;
}
}
surf.setCVs(newCVS, MSpace::kWorld);
surf.updateSurface();
}
}
3) When having CV selected in Maya, I tried to move this points with MEL commands. For this, I use the “MGlobal::executeCommand” function, but still nothing happens.
Finally, I changed executeCommand to executeCommandOnIdle. In this case, the object change correctly but the procedure crashes, perhaps, because this procedure is executed many times per second.
I would appreciate if anyone can help me with this problem or knows something about this.

Memory Alignment issue with std::map on Linux

I have run into a problem while working with c++ over Linux.
I have a base Message class which looks like this:
class MsgBase
{
public:
MsgBase( unsigned int msgid );
map < unsigned int, MSGIEBase* > messageIE_Map; // map for IEs
unsigned int messageId; // 32 bit message id
};
class Der1 is derived from MsgBase and looks like:
class Der1 : public MsgBase
{
public:
Der1 ();
virtual ~Der1 ();
// IEs
MSGIE_UINT32 ueId;
MSGIE_String configFileName;
};
Here MSGIE_UINT32 and MSGIE_String are classes derived from MSGIEBase and therefore their address can be stored in the map defined in base class above.
When Der1 is constructed the address of ueId and configFileName is stored in the map.
Here if I print the size of map ( through gdb and in the program ) it comes to be 24.
[ _M_header = 16, _M_node_count = 4, _M_key_compare = 1, 3 byte padding I suppose ].
Till here everything is fine. Now the Der1 object pointer is put inside an event object and the event is post into a queue. The event class looks like:
class Event
{
public:
MsgBase* msgPtr;
};
A different thread removes the event from the queue, extracts the msgPtr and casts it into Der1 Pointer and this is where the problem starts.
Here if I print the size of the map in the program it is 21. That means the address of the next member in the MsgBase class i.e. messageId gets shifted by 3 bytes and so the value of messageId changes completely. (when seen through gdb, the address is still intact and so is the size of the map i.e. 24 ).
This is a word alignment issue to the best of my knowledge but why is the memory alignment not consistent in different functions and why does the address of a member of a class chage when the memory to the class has been allocated using new. I am using Linux 2.6.27. , gcc version 4.1.1. , RHEL-4.
For ruling out non-virtual destructor/copy/assignment problems, please add the following to MsgBase:
public:
virtual ~MsgBase();
private:
MsgBase(MsgBase const& other);
MsgBase& operator=(MsgBase const& other);
I will try to provide all the required information step by step:
Information 1 : The relevant code.
//Step 1: Create msg and fill message Id
MsgBase*msgPtr = new Der1();
// C'tor of Der1 is as follows:
Der1::Der1 ()
: MsgBase ( ATS_SUTD_EPCTESTER_ATTACH_SCENARIO_MsgId ), // msgid is 13( 0xd )
ueId ( IE_UE_KEY, "UE", false ),
configFileName ( IE_CONFIG_FILE_NAME_KEY, "Configuration File Name", false )
{
// Insert the IEs in the map
this->addIEEntry ( IE_UE_KEY, &ueId ); // this puts entries in the map
this->addIEEntry ( IE_CONFIG_FILE_NAME_KEY, &configFileName );
}
// Step 2: Declare event and post the event
Event* event = new Event ( eventId, "Event" );
event->setData( msgPtr, hdr);
// check the message id at this stage (
cout << "msgId = " << ( ( (Der1* )msgPtr )->messageId )<< endl; // Here it comes out
// to be 0xd which is correct
// post the event
AppClass::getInstance()->addEventAndSchedule ( event );
//The queue is a member of AppClass and has been defined as
std::list <EventBase* > eventQueue;
// The code which inserts data into the queue is as follows:
bool AppClass::addEventAndSchedule ( EventBase* ev )
{
if ( ev == NULL ) return false;
this->eventQueueMutex.acquireLock();
this->eventQueue.push_back( ev );
this->eventQueueMutex.releaseLock();
// Submit Job to Scheduler
bool status = JobScheduler::getInstance()->scheduleJob( this );
return status;
}
// The event class is
class Event: public EventBase
{
public:
Event ();
virtual ~Event ();
Event ( int evId );
Event ( int evId, string evName );
MsgBase* getMessagePtr ();
void setData ( MsgBase* mPtr, Header* hPtr )
private:
// Prevent copying
Event& operator= ( Event& ev );
Event ( Event& evBase );
MsgBase* msgPtr;
Header* hdrPtr;
};
void Event::setData ( MsgBase* mPtr, Header* hPtr )
{
this->msgPtr = mPtr;
this->hdrPtr = hPtr;
}
Step 3 : Extract the event and re-print the message Id
// The code which extracts data from the queue is as follows:
void AppClass::process ()
{
EventBase* beventPtr = NULL;
this->eventQueueMutex.acquireLock();
if ( !this->eventQueue.empty() )
{
beventPtr = (EventBase* )( this->eventQueue.front() );
this->eventQueue.pop_front();
}
else
{
isQueueEmpty = true;
}
this->eventQueueMutex.releaseLock();
Event* eventPtr = ( Event* )beventPtr ;
Der1* msgPtr = (Der1* )( eventPtr->getMessagePtr()) ;
cout << "msgId = " << msgPtr->messageId << endl; // This value
//comes out to be incorrect it is now 0xd000000 i.e. a 3 byte shift
}
Information 2 : Exact problem.
The exact problem is that the 'messasgeId' is getting changed in transition. Initially it is 0xd but after popping from the queue it becomes 0xd000000. Because of this all the processing stops. The address of this parameter also changes from 0x82bd7cc to 0x82bd7c9 when printed in the program. However when seen from gdb it is still 0x82bd7cc and the value is still 0xd.
Information 3 : Compiler Flags.
Compiler Flags are same for all the files and they are:
-O0 -g3 -Wall -fmessage-length=0