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
Related
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;
}
I have got an StringHashTable class from
http://preshing.com/20110603/hash-table-performance-tests/
The following are parts of source :
class StringHashTable
{
static uint fnv1Hash(const char *key)
{
unsigned int hash = 2166136261ul;
for (const char *s = key; *s; s++)
hash = (16777619 * hash) ^ (*s);
return hash;
};
uint &operator[](const char *key)
{
uint hash = fnv1Hash(key) & (m_tableSize - 1);
Bucket *firstBucket = m_table + hash;
Bucket *b = firstBucket;
if (b->key)
{
do
{
if (strcmp(b->key, key) == 0)
return b->value;// Found existing bucket
b = b->next;
} while (b);
}
..........
}
}
Suppose that I have the global var :
StringHashTable hashtable(1024) ; //m_tableSize now 1024
And then the following is in main :
hashtable["0000"] = 0 ;
....
hashtable["9999"] = 9999 ;
After fill in all the data I need , thread 1 to n will get value according to key
while(1)
{
s = get(); //return string like "0000" ... "9999"
echo << hashtable[s.c_str()] << endl ;
}
I wonder if the StringHashTable would work fine in thread at first ,
because the function fnv1Hash is static , on second thought , there is no
static member data in this StringHashTable , so while thread1 is doing
hashtable["0000"] and thread2 is doing hashtable["9999"] at the very same time
both thread1 are calling fnv1Hash they will both get the right hash returned !!!
My question is : different thread call static uint fnv1Hash(const char *key) with
different key at the very same time still work fine ? In StringHashTable , fnv1Hash
is static for any reason ?!
The function fnv1Hash() doesn't access any non-local state other than the data pointed to by key. Assuming the content of the array key points to isn't written to concurrently, there is no threading issue. Of course, if another thread writes to the array pointed to by key, all bets are off.
Given that fnv1Hash() does access any of the object's data it doesn't need a this pointer. Thus, it is made static to indicate both to the human reader and the compiler that the objects won't be accessed implicitly. For the compiler the upshot is that it doesn't need to pass a this pointer.
class SuperClass{
/* ==================== METHODS ======================================= */
void
setValue (
std::string name,
int i ) {
MemberMapIterator it = memberMap_.find ( name );
if ( it != memberMap_.end ( ) ) {
void* ptr = ( *it ).second;
long long classPtr = reinterpret_cast< long long > ( this );
long long memberPtr = reinterpret_cast< long long > ( ptr );
int* value = reinterpret_cast< int* > ( classPtr + memberPtr );
( *value ) = i;
}
} // setValue
int
getValue (
std::string name ) {
MemberMapIterator it = memberMap_.find ( name );
if ( it != memberMap_.end ( ) ) {
void* ptr = ( *it ).second;
long long classPtr = reinterpret_cast< long long > ( this );
long long memberPtr = reinterpret_cast< long long > ( ptr );
int* value = reinterpret_cast< int* > ( classPtr + memberPtr );
return *value;
}
return -234234;
} // getValue
protected:
/* ==================== METHODS ======================================= */
void
Build ( ) {
configure ( );
} // Build
void
AddMember (
std::string name,
void* ptr ) {
memberMap_.insert ( MemberMapPair ( name, ptr ) );
} // AddMember
/* ==================== STATIC METHODS======================================= */
virtual void
configure ( ) = 0;
private:
/* ==================== METHODS ======================================= */
/* ==================== DATA MEMBERS ======================================= */
MemberMap memberMap_;
};
class SubClass: public SuperClass {
public:
/* ==================== LIFECYCLE ======================================= */
SubClass( ) : age_ ( 0 ) {
Build ( );
} /* constructor */
~SubClass( ) /* destructor */
{ }
protected:
/* ==================== STATIC METHODS======================================= */
void
configure ( ) {
long long classPtr = reinterpret_cast< long long > ( this );
long long agePtr = reinterpret_cast< long long > ( &this->age_ );
void* ptr = reinterpret_cast< void* > ( agePtr - classPtr );
this->AddMember ( "age", ptr );
} // configure
private:
/* ==================== DATA MEMBERS ======================================= */
int age_;
}
In SubClass, I add the offset of the private class field (thinking about the class as a C structure) the Super class map using string name as a key.I will make to execute configure only once and then I want to use this offset for every Person instance to access to its private fields at runtime (this + offset = field). Will be this safe? I tested this code and its work it is doing what I want. But should I expect any memory violations or something else (assuming that it won't be intentional violation (programmer errors))?
First of all, it's worth knowing that C++ classes are not like C structs. The compiler puts extra things in classes like the vtable pointer, which could be in the beginning, the end, or somewhere else depending on the compiler. There is one kind of class that behaves like a C struct (i.e. a bag of bits) and they're called Plain Old Data types (POD). You can find plenty on them on StackOverflow. Since you're using inheritance, you're not using a POD.
If you're trying to forcefully access private members, you probably need to rework your design. You should ask yourself why they're private in the first place. Based on what it looks like you're going for in the code, I can think of more straightforward approaches:
Cast the base class to the subclass, then set the private member with a setter function.
You could make setValue and getValue virtual and override it in the subclass.
Use friendship.
I'm designing an observer pattern which should work this way: observer calls AddEventListener method of EventDispatcher and passes a string which is the name of the event, PointerToItself and a PointerToItsMemberMethod
After that event happens inside of the EventDispatcher; it looks through the list of subscriptions and if there are some, assigned to this event calls the action method of the observer.
I've come to this EventDispatcher.h. CAUTION contains bit of pseudo-code.
The are two questions:
How do I define the type of action in struct Subscription?
Am I moving the right way?
PS: No, I'm not gonna use boost or any other libraries .
#pragma once
#include <vector>
#include <string>
using namespace std;
struct Subscription
{
void* observer;
string event;
/* u_u */ action;
};
class EventDispatcher
{
private:
vector<Subscription> subscriptions;
protected:
void DispatchEvent ( string event );
public:
void AddEventListener ( Observer* observer , string event , /* u_u */ action );
void RemoveEventListener ( Observer* observer , string event , /* u_u */ action );
};
This header implements like this in EventDispatcher.cpp
#include "EventDispatcher.h"
void EventDispatcher::DispatchEvent ( string event )
{
int key = 0;
while ( key < this->subscriptions.size() )
{
Subscription subscription = this->subscriptions[key];
if ( subscription.event == event )
{
subscription.observer->subscription.action;
};
};
};
void EventDispatcher::AddEventListener ( Observer* observer , string event , /* */ action )
{
Subscription subscription = { observer , event , action );
this->subscriptions.push_back ( subscription );
};
void EventDispatcher::RemoveEventListener ( Observer* observer , string event , /* */ action )
{
int key = 0;
while ( key < this->subscriptions.size() )
{
Subscription subscription = this->subscriptions[key];
if ( subscription.observer == observer && subscription.event == event && subscription.action == action )
{
this->subscriptions.erase ( this->subscriptions.begin() + key );
};
};
};
You could either define an Action class or pass a lambda function (C++11). In the latter case, action could be defined as
function<void (EventDispatcher*)> action;
and you would register the observer as follows
Observer * me = this;
observable->AddEventListener (this, "EventName", [me] (EventDispatcher* dispatcher) {
// code here; me is available
});
You should probably use smart weak pointers to store the Observers in the EventDispatcher, such that you do not have to care for un-registering.
Edit: Added following example (just one subscription possible, but should illustrate the idea -- you have to be careful that you do not reference an object that does no longer exist)
struct Observable {
std::weak_ptr<function<void (const Observable&)>> action;
void AddEventListener (std::weak_ptr<function<void (const Observable&)>> theAction) {
action = theAction;
}
void EventRaised () {
if (!action.expired ()) {
auto theAction = action.lock ();
(*theAction) (*this);
}
}
};
struct Observer {
...
void CallOnEvent (const Observable & observable) {
// do something
}
// field to store the action as long as it is needed
std::shared_ptr<function<void (const Observable&)>> action;
void ... {
auto me = this;
action = std::make_shared<function<void (const Observable&)>> (
[me] (const Observable& observable) {
me->CallOnEvent (observable);
}
);
// we could have as well used std::bind
observable.AddEventListener (action);
}
};
Perhaps you should just create a class to be derived by "users":
class Action {
public:
friend class EventDispatcher;
virtual SomeResultType DoThis() = 0;
private:
/* Some common data */
};
Just pass some derived-from-class-Action typed variable to AddEventListener. When the corresponding event is triggered, just fill in the common data and call the DoThis() method.
void EventDispatcher::DispatchEvent ( string event )
{
int key = 0;
while ( key < this->subscriptions.size() )
{
Subscription subscription = this->subscriptions[key];
if ( subscription.event == event )
{
subscription->action();
};
};
};
For AddEventListener:
void EventDispatcher::AddEventListener ( Observer* observer , string event , Action* action )
{
Subscription subscription = { observer , event , action );
this->subscriptions.push_back ( subscription );
};
An example of a Action derived class:
class myAction: public Action {
public:
// Implement the DoThis() method
void SomeResultType DoThis() {
cout << "Hello World!";
return SomeValue;
}
};
// To use the action,
myAction* act = new myAction;
myEventDispatcher.AddEventListener(someObserver, "HelloWorld", act);
This is one of the safest way to implement actions (and callbacks).
In its simplest form u_u could be a function pointer e.g.
typedef void (*u_u)(void*); // or whatever arguments u like
then you just supply a function that is called whenever the event is triggered.
void myaction(void* arg)
{
...
}
Subscription s;
...
s.action = myaction;
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