user37103: I am sending a polymorphic object over serial between two Arduinos. The transmission should be fine, indeed if on the receiver side I static_cast the pointer to the Derived class it works properly. On the other hand if I try to call virtual functions on the Base pointer, Arduino resets. What is causing this behaviour?
Some samples of the code follows.
Sender:
RS485_Serial bus;
void loop ()
{
  Random r(1); //targeting device 1 in the bus
  if (r.request(bus)) { blink(r.val); } //make a request for a random number
                                        //blink the led the given number of times

  delay(1000);
}

Receiver:
RS485_Serial bus;
bus.set_address(1);
void loop ()
{
  listen(bus);
} 

Selected common parts:
struct Action {
  byte target_address;

  Action(byte addr): target_address(addr) {}
  virtual ~Action() {}

  virtual size_t size() const { return sizeof(*this); }
  virtual int  vrequest(RS485_Serial &) = 0;
  virtual void vrespond(RS485_Serial &) = 0;

  int request(RS485_Serial & bus) {
    bus.write(reinterpret_cast<byte*>(this), size());
    return vrequest(bus);
  }
  void respond(RS485_Serial & bus) {
    vrespond(bus); // <--- This virtual call makes the sender reset
  }
};

struct Random: Action {
  size_t size() const override { return sizeof(*this); }
  int val;
  Random(byte address): Action(address) {}

  int vrequest(RS485_Serial & bus) override {
    return bus.read(val);
  }
  void vrespond(RS485_Serial & bus) override {
    bus.write(static_cast<decltype(val)>(random(2,5)));
  }
};

void listen(RS485_Serial & bus) {
  byte * data = nullptr;
  byte length = 0;
  if ( bus.read(data, length) ){
    Action & a = *(reinterpret_cast<Action*>(data));
    if (a.size() == length) blink(3);
    if (a.target_address == bus.address) {
      a.respond(bus);
      //static_cast<Random*>(&a)->vrespond(); works but it has no point
    }
  }
}

My doubt is that if the vtable is stored in different positions, than the vtable pointer in the object obtained by the receiver will be off, causing the crash.

user-1: I think http://stackoverflow.com is the correct forum for your question. Your problem is how to serialize/deserialize correctly an object in C++. 
An easy way to do it is simply send the values (not the object) and recreate the object at the other side. So, now your problem is reduced to send and receive a bunch of int's, float's, string's, whatever.
Why you want/need to do that?

user4143: I suspect then that the object contains a pointer to the code for vrespond, which is at a specific (and differing from program to program) location in flash memory. An object in C++ isn't a single atomic item, it is a collection of data and pointers to functions. On a Harvard architecture system the data is in RAM and the code is in Flash (you cannot typically execute code from RAM). The compiler chooses where to place the code in Flash when it compiles (well, the linker does). That won't be the same address in different programs. All you are doing is sending over the addresses in flash that the code resides at - and those addresses are incorrect. By specifically casting it to a type that has code available you are also telling it where that code resides. Without that manual cast you are having to rely on the (incorrect) function pointers.
It is a bad idea to transfer objects like that from one system to another. It is better to transfer just the data and feed that data into an existing object created on the receiver. How you send and receive that data and feed it into the object is up to you. 

37103: <p>I am sending a polymorphic object over serial between two Arduinos. The transmission should be fine, indeed if on the receiver side I <code>static_cast</code> the pointer to the <code>Derived</code> class it works properly. On the other hand if I try to call virtual functions on the <code>Base</code> pointer, Arduino resets. What is causing this behaviour?</p>

<p>Some samples of the code follows.</p>

<p>Sender:</p>

<pre><code>RS485_Serial bus;
void loop ()
{
  Random r(1); //targeting device 1 in the bus
  if (r.request(bus)) { blink(r.val); } //make a request for a random number
                                        //blink the led the given number of times

  delay(1000);
}
</code></pre>

<p>Receiver:</p>

<pre><code>RS485_Serial bus;
bus.set_address(1);
void loop ()
{
  listen(bus);
} 
</code></pre>

<p>Selected common parts:</p>

<pre><code>struct Action {
  byte target_address;

  Action(byte addr): target_address(addr) {}
  virtual ~Action() {}

  virtual size_t size() const { return sizeof(*this); }
  virtual int  vrequest(RS485_Serial &amp;) = 0;
  virtual void vrespond(RS485_Serial &amp;) = 0;

  int request(RS485_Serial &amp; bus) {
    bus.write(reinterpret_cast&lt;byte*&gt;(this), size());
    return vrequest(bus);
  }
  void respond(RS485_Serial &amp; bus) {
    vrespond(bus); // &lt;--- This virtual call makes the sender reset
  }
};

struct Random: Action {
  size_t size() const override { return sizeof(*this); }
  int val;
  Random(byte address): Action(address) {}

  int vrequest(RS485_Serial &amp; bus) override {
    return bus.read(val);
  }
  void vrespond(RS485_Serial &amp; bus) override {
    bus.write(static_cast&lt;decltype(val)&gt;(random(2,5)));
  }
};

void listen(RS485_Serial &amp; bus) {
  byte * data = nullptr;
  byte length = 0;
  if ( bus.read(data, length) ){
    Action &amp; a = *(reinterpret_cast&lt;Action*&gt;(data));
    if (a.size() == length) blink(3);
    if (a.target_address == bus.address) {
      a.respond(bus);
      //static_cast&lt;Random*&gt;(&amp;a)-&gt;vrespond(); works but it has no point
    }
  }
}
</code></pre>

<p>My doubt is that if the vtable is stored in different positions, than the vtable pointer in the object obtained by the receiver will be off, causing the crash.</p>
 -1: <p>I think <a href="http://stackoverflow.com">http://stackoverflow.com</a> is the correct forum for your question. Your problem is how to serialize/deserialize correctly an object in C++. </p>

<p>An easy way to do it is simply send the values (not the object) and recreate the object at the other side. So, now your problem is reduced to send and receive a bunch of int's, float's, string's, whatever.</p>

<p>Why you want/need to do that?</p>
 4143: <p>I suspect then that the object contains a pointer to the code for <code>vrespond</code>, which is at a specific (and differing from program to program) location in flash memory. An object in C++ isn't a single atomic item, it is a collection of data and pointers to functions. On a Harvard architecture system the data is in RAM and the code is in Flash (you cannot typically execute code from RAM). The compiler chooses where to place the code in Flash when it compiles (well, the linker does). That won't be the same address in different programs. All you are doing is sending over the addresses in flash that the code resides at - and those addresses are incorrect. By specifically casting it to a type that has code available you are also telling it where that code resides. Without that manual cast you are having to rely on the (incorrect) function pointers.</p>

<p>It is a bad idea to transfer objects like that from one system to another. It is better to transfer just the data and feed that data into an existing object created on the receiver. How you send and receive that data and feed it into the object is up to you. </p>
