从QML调用C ++方法时,我遇到了分段错误。 segfault的原因是函数endResetModel()
,但它在退出此函数后会发生,正如您在堆栈跟踪中看到的那样。
堆栈跟踪:
==12651== Process terminating with default action of signal 11 (SIGSEGV)
==12651== Access not within mapped region at address 0x8
==12651== at 0x601BB4E: QtQml::qmlExecuteDeferred(QObject*) (in /opt/Qt/5.7/gcc_64/lib/libQt5Qml.so.5.7.0)
==12651== by 0x5146708: QQuickTransition::prepare(QList<QQuickStateAction>&, QList<QQmlProperty>&, QQuickTransitionManager*, QObject*) (in /opt/Qt/5.7/gcc_64/lib/libQt5Quick.so.5.7.0)
==12651== by 0x513D443: QQuickTransitionManager::transition(QList<QQuickStateAction> const&, QQuickTransition*, QObject*) (in /opt/Qt/5.7/gcc_64/lib/libQt5Quick.so.5.7.0)
==12651== by 0x69D077C: QMetaObject::activate(QObject*, int, int, void**) (in /opt/Qt/5.7/gcc_64/lib/libQt5Core.so.5.7.0)
==12651== by 0x69D077C: QMetaObject::activate(QObject*, int, int, void**) (in /opt/Qt/5.7/gcc_64/lib/libQt5Core.so.5.7.0)
==12651== by 0x8064FB7: QQuickAbstractButton::mouseReleaseEvent(QMouseEvent*) (in /opt/Qt/5.7/gcc_64/lib/libQt5QuickTemplates2.so.5.7.0)
==12651== by 0x51DA707: QQuickItem::event(QEvent*) (in /opt/Qt/5.7/gcc_64/lib/libQt5Quick.so.5.7.0)
==12651== by 0x69A8989: QCoreApplication::notify(QObject*, QEvent*) (in /opt/Qt/5.7/gcc_64/lib/libQt5Core.so.5.7.0)
==12651== by 0x69A8ADF: QCoreApplication::notifyInternal2(QObject*, QEvent*) (in /opt/Qt/5.7/gcc_64/lib/libQt5Core.so.5.7.0)
==12651== by 0x51EC089: QQuickWindow::sendEvent(QQuickItem*, QEvent*) (in /opt/Qt/5.7/gcc_64/lib/libQt5Quick.so.5.7.0)
==12651== by 0x51EC811: QQuickWindowPrivate::deliverMouseEvent(QMouseEvent*) (in /opt/Qt/5.7/gcc_64/lib/libQt5Quick.so.5.7.0)
==12651== by 0x51EF1F4: QQuickWindow::mouseReleaseEvent(QMouseEvent*) (in /opt/Qt/5.7/gcc_64/lib/libQt5Quick.so.5.7.0)
==12651== If you believe this happened as a result of a stack
==12651== overflow in your program's main thread (unlikely but
==12651== possible), you can try to increase the size of the
==12651== main thread stack using the --main-stacksize= flag.
==12651== The main thread stack size used in this run was 8388608.
我的C ++函数没有做任何事情,只是试图捕捉这个错误:
Q_INVOKABLE void qml_del_account(int index);
void Identities::qml_del_account(int index) {
beginResetModel();
endResetModel();
}
奇怪的是,只有当我从qml_del_account()
对象的孩子调用ListView
时,才会发生分段错误。正如您在QML上看到的,我可以从2个位置,从按钮和菜单中调用此函数。
QML:
Identities {
id: identities
}
Pane {
anchors {
fill: parent
}
Rectangle {
id: list_area
border.color: "black"
border.width: 2
anchors {
left: parent.left
right: parent.right
top: parent.top
bottom: parent.bottom
}
Column {
ListView {
id: list_identities
width: list_area.width
height: 100
model: identities
delegate: Rectangle {
height: 40
width: parent.width
Text {
id: identities_item
height: parent.height
anchors.left: parent.left
width: 100
text: email
}
ToolButton {
anchors.right: parent.right
contentItem: Image {
source: "qrc:/images/dots-menu.png"
id: toolbtn_img
width: 24
height: 24
}
onClicked: optionsMenu.open()
Menu {
id: optionsMenu
MenuItem {
text: "Delete"
onTriggered: {
identities.qml_del_account(index) // <-- this call DOES produce a SEGFAULT
}
}
}
}
}
}
Button {
text: "del"
onClicked: {
identities.qml_del_account(0) // <-- this call DOES NOT produce a SEGFAULT
}
}
}
}
}
所以,正如我所说,有2个用例,但只有1个产生SEGFAULT:
所以我的问题是:当调用对象是模型视图的子代时,我可以通过C ++代码重置我的模型吗? (我的例子中是 list_identities 对象)。
或者,可能我在其他代码中有一些错误弄乱了我的对象树,希望不会,valgrind对这种可能性一无所知。