嗨,
当我想使用带有以下代码的QTcpSocket时,我得到了SIGSEGV。 (底部有更多说明)
用于创建QTTCPSocket(将保留QTcpSocket指针)的函数:
std::shared_ptr<QTTCPSocket> createQtSocket(std::string host, unsigned int port)
{
QTcpSocket *sock = new QTcpSocket;
sock->connectToHost(QHostAddress(QString::fromStdString(host)), port);
if (!sock->waitForConnected())
throw std::runtime_error("Connection refused");
return std::make_shared<QTTCPSocket>(sock);
}
QTTCPSocket类:
class QTTCPSocket {
public:
QTTCPSocket(QTcpSocket *socket)
: _socket(socket)
{};
~QTTCPSocket() = default;
void send(const std::string &msg)
{
std::cout << msg << std::endl;
_socket->write(&msg[0], static_cast<qint64>(msg.length())); // produces a SIGSEGV if called from a qt event (a button for example)
_socket->waitForBytesWritten(0);
}
private:
QTcpSocket *_socket;
};
主要功能:
int main()
{
std::shared_ptr<QTTCPSocket> socket = createQtSocket("127.0.0.1", 33333);
ViewStateMachine vsm(socket);
vsm.init();
vsm.start();
}
ViewStateMachine类(hpp):
class ViewStateMachine {
public:
ViewStateMachine(std::shared_ptr<QTTCPSocket> sock);
void init();
void start();
std::shared_ptr<QTTCPSocket> getSock();
private:
LoginView *_loginView;
std::shared_ptr<QTTCPSocket> _sock;
};
ViewStateMachine类(cpp):
#include "ViewStateMachine.hpp"
ViewStateMachine::ViewStateMachine(std::shared_ptr<QTTCPSocket> socket)
: _sock(std::move(socket))
{
}
void ViewStateMachine::init()
{
_loginView = new LoginView(this);
_loginView->init();
}
void ViewStateMachine::start()
{
_loginView->show();
}
std::shared_ptr<QTTCPSocket> ViewStateMachine::getSock()
{
_sock->send("test1"); // SIGSEGV inside (check above)
return _sock; // if I remove _sock->send("test1"), it SIGSEGV in the shared_ptr's constructor (only if called from a qt event (a button for example)
}
LoginView是一个被动类,它通过QObject::connect(_connectBtn, SIGNAL(clicked()), this, SLOT(onClick_connectBtn()));
的成员函数onClick_connectBtn()
向LoginView
注册事件。
所有这些代码段可能会造成混淆,因此在这里进行逐步说明:
main()
开始:创建一个QTcpSocket *
中包含的QTTCPSocket class
中包含的std::shared_ptr<QTTCPSocket>
。ViewStateMachine
创建一个shared_ptr
实例,该实例将存储在该实例中。我们将其称为vsm
。vsm.init()
,它将使用LoginView
(this
)创建一个vsm
实例。 LoginView
将存储ViewStateMachine
实例。vsm.start()
,它将调用_loginView.show()
(来自QT的QWidget),它将显示登录视图。一切正常,我们可以看到登录视图。
但是,如果我想在LoginView中使用我的套接字:
*当我想从_loginView->init()
或在LoginView的构造函数中使用它时,它很好用!
*当我想从LoginView::onClick_connectBtn
中使用它(由QT调用,也许在诸如构造函数之类的特殊环境中,不确定)时,它会产生SIGSEGV,我在上面的代码(shared_ptr的构造函数或来自QT'套接字)。
要从LoginView
获取套接字,我使用ViewStateMachine::getSock()
(_viewStateMachine->getSock()
)。
Valgrind显示
pure virtual method called
terminate called without an active exception
shared_ptr的构造函数使用互斥量递增值时会生成SIGSEGV。
当我使用_socket
(QT'套接字)时,写SIGSEGV。指针地址从头到尾没有变化。
如果还有其他问题,请询问!
非常感谢您的帮助:)。
编辑:如果我用C指针替换每个std :: shared_ptr,它将起作用。