公共成员未初始化

时间:2014-01-15 20:57:15

标签: c++ qt class initialization

我正在制作客户端服务器应用程序,服务器具有GUI。我正在使用Qt。 对于沟通我使用管道。

我已将服务器应用程序划分为后端和GUI。后端有一个PipeServer类,在GUI中,我有覆盖onReceiveMessage等函数。

一切正常,直到我决定添加一个std :: queue作为基类成员。

在应用程序开始时,我得到一个异常,经过检查,我的队列似乎没有以0个元素开头。事实上,似乎队列根本没有初始化。有两种可能性:可能是因为我的GUI类继承了2个类,并且不知何故第二个基类,我的PipeServer没有正确初始化其成员,或者可能是因为pipeServerGUI对象被移动到另一个线程QT。

关于如何解决这个问题的任何想法?

相关代码:

class HookServer
{
    PIPEINST Pipe[INSTANCES]; 
    HANDLE hEvents[INSTANCES]; 

    VOID DisconnectAndReconnect(DWORD); 
    BOOL ConnectToNewClient(HANDLE, LPOVERLAPPED); 
    VOID GetAnswerToRequest(LPPIPEINST); 

public:
    std::queue<std::string> messages;

    int init(std::string pipename);
    int run();
    virtual void onNewConnection() {};
    virtual void onReceiveMessage(std::string message) {};
};

class HookServerGUI : public QObject, public HookServer
{
    Q_OBJECT
    void onReceiveMessage(std::string message);
    void onNewConnection();

    public slots:

    void doWork() {
        init("\\\\.\\pipe\\hookpipe");
        run();
    }

    signals:
    void signalGUI(QString message);
};

    //GUIServerCreation

    QThread *thread = new QThread;
    HookServerGUI* worker = new HookServerGUI;
    QObject::connect(worker,SIGNAL(signalGUI(const QString&)),this,SLOT(processMessage(const QString&)));

    worker->moveToThread(thread);
    thread->start();



    QMetaObject::invokeMethod(worker, "doWork", Qt::QueuedConnection);

编辑:

例外是访问冲突异常。它出现在这部分代码中:

VOID HookServer::GetAnswerToRequest(LPPIPEINST pipe)
{
    onReceiveMessage(pipe->chRequest);
    if(!messages.empty())
    {
        std::string s = messages.front();
        messages.pop();
        strcpy(pipe->chReply,s.c_str());
        pipe->cbToWrite = strlen(s.c_str()+1);
    }
}

由于messages.empty()返回一些巨大的数字,它会尝试读取第一个对象并以某种方式失败。

也没有PipeServerGUI构造函数。

EDIT2:

我通过在new HookServerGUI();

之后放置括号来解决部分问题

问题是该函数仍然无效,并引发访问冲突异常。它发生在front()行。在调试器中检查时,该函数确实有1个元素,因此它不是因为它是空的。有什么想法吗?

EDIT3:

第二次运行时,不幸的是queue.size()仍然不正确。看起来像是对我的数据竞争。

1 个答案:

答案 0 :(得分:0)

问题出现在你没有展示的代码中,这是一个典型的内存错误案例,它看起来像。某些代码在某处写入它不拥有的内存。可能你在使用winapi的方式上有一个错误。您需要创建一个最小的,独立的测试用例。

我认为你可能会因为不使用QLocalSocket而在脚下拍摄:在Windows上,它是一个命名管道 - 正是你想要的。

此外,这是C ++代码。完全没有理由将PIPEINST或HANDLE放入原始C数组中。使用QVectorstd::vector。可能其余的代码充满了像这样的C-isms,而某些地方出了问题。

我不会忽略缓冲区溢出,因为显然你忽略了PIPEINST中缓冲区的大小 - strcpy可以超出缓冲区。我也不确定PIPEINST from the example code使用的字符类型与std::string::c_str()返回的字符类型相同。

即使你想使用没有QLocalSocket的显式管道来实现你的代码,你仍然应该使用C ++,QString等,并了解你的数据发生了什么。