I have a class derived from an interface
class Interface {
public:
virtual void foo() = 0;
};
class Implementer : public Interface {
public:
void foo() override { std::cout << "Hello world" << std::endl; }
private:
int __some_int_member;
};
Now I want to write a program, which will get the same instance of Implementer
class in all application instances. I followed the example suggested here (the second one), but in that example, only a single byte is being used.
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
Implementer *impl = nullptr;
QSystemSemaphore accessor("app_accessor", 1);
accessor.acquire();
#ifndef QT_OS_WIN
QSharedMemory mem_fix("my_class");
if(mem_fix.attach())
{
mem_fix.detach();
}
#endif
QSharedMemory mem("my_class");
if(!mem.attach())
{
mem.create(sizeof(Implementer));
new(mem.data()) Implementer();
}
impl = (Implementer*)mem.data();
accessor.release();
impl->foo();
return app.exec();
}
The first instance works fine. But it crashes for the second one on line impl->foo()
.
I think the reason is a bad cast from void*
to the Implementer*
. But I don't know how to do that correctly.
Any suggestions?
I realized, that the crash caused by the Segmentation fault was the result of inheritance because without the base class everything works just fine.
After some debugging, memory dump and some comments, I realized, that the problem is that in runtime the first instance of the program creates the vtable
in its stack and puts the vptr
to its vtable
. The second instance gets the same vptr
which, unfortunately, points to some random memory (that might be allocated or not).
A base class with virtual functions requires a vtable
. The memory location of the vtable or even the existence of it is implementation-dependent, thus you get an exception when you try to access a function via vtable
.
What you can do is separate the data and logic. Define a new class with only data, share that and apply some functions on it.
However, it seems like you are going to have some more issues since you are planning to share QMap
as data. It probably stores its data on the heap and does not provide a memory allocator interface (at least I couldn't see). Meaning that you won't be able to control where it allocates the data. If you are certain that you need a map structure, you can use std::map
and provide your own memory allocator to the map which uses the shared memory you've created. I've just written c++ std map custom memory allocator
in google and it shows some solutions. There is also this question in SO that may help you.