C++ Segmentation fault - messages between 2 applications

230 Views Asked by At

I have 2 different applications, a sender and a receiver. the Sender will send a message over to the receiver, who will decode the message and print to the console. However, I keep getting segmentation fault error.

Both sender and receiver application have the same TestContainer.h and TestContainer.cpp.

Casting method

template<class To,class From>To cast(From v)
{
        return static_cast<To>(static_cast<const void*>)(v);
}

Sender application

int main()
{
    TestContainer tc;
    tc.setDesc("this is a message");
    const char* castedData = cast<const char*>(&tc);

    const TestContainer test_tc = cast<const TestContainer*>(castedData);

    // i get back "this is a message",so the casting is working
    cout << "message content: " << test_tc->getDesc() <<endl;

    TaoSender;      
    TaoSender.send(castedData);     

    return 1;
}

Receiver Application

void push(const RtecEventComm::EventSet& events)
{
    const char* receivedData;
    events[0].data.any_value >>= receivedData;

    cout << "data received: " << receivedData << endl;

    const TestContainer rcv_tc = cast<const TestContainer*>(receivedData);

    cout << "message content: " << rcv_tc->getDesc() <<endl; // error(segmentation fault)
}

TestContainer.h and TestContainer.cpp

class TestContainer{
    public 
        TestContainer();
        virtual ~TestContainer();
        const std:string& getDesc () const {
            return desc;
        }
        void setDesc(const std::string& desc) {
            this->desc = desc;
        }
    private
        std::string desc;
}



#include TestContainer.h

TestContainer::TestContainer(){}
TestContainer::~TestContainer(){}

The value of castedData at the sender and the value of receivedData at the receiver is the same, so I guess the message sending is correct.

However,at the Receiver, after converting the receivedData buffer to a Testcontainer pointer and attempting to access the desc, I get a segmentation fault error.

I also tried casting back to Testcontainer in the Sender, and I am able to access the desc. So what did I miss out?

1

There are 1 best solutions below

0
davmac On

Although the code in your question contains errors, if I understand you correctly you are trying to push the representation of an object over a pipe or other channel to another process, where you reconstruct the object and try to use it.

You could do this with "Plain Old Data" objects, but the TestContainer class has virtual methods and therefore it is not POD. In most implementations of C++, objects of type TestContainer will contain a vtable pointer which refers to a table allocated within the process' address space. The address of this table will likely be different in different processes. Therefore, copying the representation of the TestContainer object byte-by-byte to another process will lead to crashes when you try to call a virtual method.

TestContainer instances also contain a std::string. A string allocates storage to hold the string contents and this storage will be outside the objecet itself. Transmitting the byte representation of the string as part of TestContainer results in reconstruction at the other end of a string that holds a pointer to a memory address in another process. Within the receiver, that memory address will refer to something else. Hence, the string will not be successfully reconstructed.

To send objects between processes you need to properly transmit them in a form that is independent of memory addresses contained within (whether that be a vtable pointer, a pointer member, or a pointer member of a an opaque member such as a string). The process of converting data to such a form is called serialization. There are libraries available to assist with this, but nothing in the standard library.