gpt4 book ai didi

c++ - 如何正确地将带有 vtable 的类实例写入和读取到 QSharedMemory 中?

转载 作者:行者123 更新时间:2023-11-28 04:12:52 27 4
gpt4 key购买 nike

我有一个从接口(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;
};

现在我想编写一个程序,它将在所有应用程序实例中获取相同的 Implementer 类实例。我按照建议的例子 here (第二个),但在那个例子中,只使用了一个字节。

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();
}

第一个实例工作正常。但是它在 impl->foo() 上的第二个崩溃。

我认为原因是从 void*Implementer* 的错误转换。但我不知道如何正确地做到这一点。

有什么建议吗?

编辑

我意识到,Segmentation fault 导致的崩溃是继承的结果,因为没有基类一切正常。

编辑2

经过一些调试、内存转储和一些注释后,我意识到,问题是在运行时程序的第一个实例在其堆栈中创建了 vtable 并将 vptr 到它的 vtable。第二个实例获得相同的 vptr,不幸的是,它指向一些随机内存(可能已分配或未分配)。

最佳答案

具有虚函数的基类需要一个vtableThe memory location of the vtable or even the existence of it is implementation-dependent ,因此当您尝试通过 vtable 访问函数时会出现异常。

您可以做的是将数据和逻辑分开。定义一个只有数据的新类,共享它并在其上应用一些功能。

但是,由于您计划将 QMap 作为数据共享,因此您似乎还会遇到更多问题。它可能将其数据存储在堆上并且不提供内存分配器接口(interface)(至少我看不到)。这意味着您将无法控制它在何处分配数据。如果您确定需要映射结构,则可以使用 std::map 并为使用您创建的共享内存的映射提供您自己的内存分配器。我刚刚在 google 中编写了 c++ std map custom memory allocator,它显示了一些解决方案。还有this SO 中的问题可能对您有帮助。

关于c++ - 如何正确地将带有 vtable 的类实例写入和读取到 QSharedMemory 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57298775/

27 4 0
文章推荐: javascript - 禁用超时按钮
文章推荐: javascript - 有什么方法可以设置