C++ Qt QString Q_属性导致SIGSEGV

C++ Qt QString Q_属性导致SIGSEGV,c++,qt,qt4,segmentation-fault,qstring,C++,Qt,Qt4,Segmentation Fault,Qstring,前几天我遇到了这个问题,这让我大吃一惊,并停止了测试。我在正常应用程序之外开发一个功能,我遇到了一个Q_属性的问题,我似乎无法理解。我已经将情况简化为仍然复制SIGSEGV的基本情况。我的代码有一个注释开关块,它包含或删除了一个附加的Q_属性“prop2”,当我只有一个属性“prop1”时,我没有得到seg错误。当我添加附加属性“prop2”时,我得到seg错误。我已经包括了所有东西——包括一堆gdb。任何帮助/建议都将不胜感激 系统:Ubuntu12.04LTS(地球上最伟大的操作系统) Qt

前几天我遇到了这个问题,这让我大吃一惊,并停止了测试。我在正常应用程序之外开发一个功能,我遇到了一个Q_属性的问题,我似乎无法理解。我已经将情况简化为仍然复制SIGSEGV的基本情况。我的代码有一个注释开关块,它包含或删除了一个附加的Q_属性“prop2”,当我只有一个属性“prop1”时,我没有得到seg错误。当我添加附加属性“prop2”时,我得到seg错误。我已经包括了所有东西——包括一堆gdb。任何帮助/建议都将不胜感激

系统:Ubuntu12.04LTS(地球上最伟大的操作系统) Qt:4.8(与apt get install Qt sdk一起安装)

文件:MyObject.hpp

#ifndef MYOBJECT_HPP
#define MYOBJECT_HPP

#include <QObject>

class MyObject : public QObject {
    Q_OBJECT
    Q_PROPERTY(QString prop1 READ prop1 WRITE setProp1 RESET resetProp1)
    //* add/remove comment
    Q_PROPERTY(QString prop2 READ prop2 WRITE setProp2 RESET resetProp2) 
    // end */
private:
    QString m_prop1;
    //* add/remove comment
    QString m_prop2;
    // end */
public:
    MyObject(QObject * parent = 0):QObject(parent){
        resetProp1();
        //* add/remove comment
        resetProp2();
        // end */
    }
    virtual ~MyObject(){ }
    QString prop1() const{
        return m_prop1;
    }
    QString setProp1(const QString& prop1){
        m_prop1 = prop1;
    }
    void resetProp1(){
        setProp1("reset");
    }
    //* add/remove comment
    QString prop2() const{
        return m_prop2;
    }
    QString setProp2(const QString& prop2){
        m_prop2 = prop2;
    }
    void resetProp2(){
        setProp2("reset");
    }
    // end */
};

#endif
gdb输出:

Reading symbols from /home/me/temp/string_seg_test/build/test...done.
(gdb) run
Starting program: /home/me/temp/string_seg_test/build/test 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7fffe7fc6700 (LWP 9297)]
[New Thread 0x7fffe77c5700 (LWP 9298)]
[New Thread 0x7fffe6354700 (LWP 9299)]

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff6d00bbd in QString::operator=(QString const&) () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
(gdb) bt
#0  0x00007ffff6d00bbd in QString::operator=(QString const&) () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#1  0x0000000000401b43 in MyObject::setProp2 (this=0x7fffffffe11000, prop2=...)
    at /home/me/temp/string_seg_test/src/MyObject.hpp:39
#2  0x0000000000401b7f in MyObject::resetProp2 (this=0x7fffffffe11000)
    at /home/me/temp/string_seg_test/src/MyObject.hpp:42
#3  0x000000000040197b in MyObject::MyObject (this=0x7fffffffe11000, parent=0x0)
    at /home/me/temp/string_seg_test/src/MyObject.hpp:21
#4  0x000000004017ee00 in ?? ()
#5  0x007fffffffe23800 in ?? ()
#6  0x0000010040154b00 in ?? ()
#7  0x000000004021b000 in ?? ()
#8  0x000000007ef92000 in ?? ()
#9  0x000000007ef9b000 in ?? ()
#10 0x0000000060310000 in ?? ()
#11 0x007ffff7d9a9d000 in ?? ()
#12 0x00000000604d2000 in ?? ()
#13 0x007fffffffe23000 in ?? ()
#14 0x0000000000000000 in ?? ()
(gdb) 

这是一个简单的问题。您的setter方法返回
QString
,但您从未从这些方法返回任何内容。就这样一声巨响。setter应具有以下签名:
void setPropx(const QString&)

您的编译器很可能已经警告过您这一点。因此,教训是:不要忽略编译器警告。理解他们的意思

另一方面,你留下了很多不相关的东西。如果您一直有系统地逐行剥离内容,您最终会得到一个更小的单文件示例。不需要
QObject
和应用程序实例,也不需要
resetProp()
的间接寻址,也不需要getter

最小化的最后两个步骤应该是:

// Step N-1
#include <QString>
class C {
    QString m_prop1, m_prop2;
public:
    C() { setProp1("reset"); setProp2("reset"); }
    QString setProp1(const QString& prop1) { m_prop1 = prop1; }
    QString setProp2(const QString& prop2) { m_prop2 = prop2; }
} c;
int main(int, char **) {
    return 0;
}

// Step N
#include <QString>
class C {
    QString m_prop1;
public:
    C() { setProp1("reset"); setProp1("reset"); }
    QString setProp1(const QString& prop1) { m_prop1 = prop1; }
} c;
int main(int, char **) {
    return 0;
}
//步骤N-1
#包括
C类{
QString m_prop1,m_prop2;
公众:
C(){setProp1(“重置”);setProp2(“重置”);}
QString setProp1(const QString&prop1){m_prop1=prop1;}
QString setProp2(const QString&prop2){m_prop2=prop2;}
}c;
int main(int,char**){
返回0;
}
//步骤N
#包括
C类{
QString m_prop1;
公众:
C(){setProp1(“重置”);setProp1(“重置”);}
QString setProp1(const QString&prop1){m_prop1=prop1;}
}c;
int main(int,char**){
返回0;
}
此时,你可能已经注意到了问题所在

所有内容都应该在一个文件中。单独的标题等只是分散注意力,使你的问题更长。这是您应该发布的内容:)

Reading symbols from /home/me/temp/string_seg_test/build/test...done.
(gdb) run
Starting program: /home/me/temp/string_seg_test/build/test 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7fffe7fc6700 (LWP 9297)]
[New Thread 0x7fffe77c5700 (LWP 9298)]
[New Thread 0x7fffe6354700 (LWP 9299)]

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff6d00bbd in QString::operator=(QString const&) () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
(gdb) bt
#0  0x00007ffff6d00bbd in QString::operator=(QString const&) () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#1  0x0000000000401b43 in MyObject::setProp2 (this=0x7fffffffe11000, prop2=...)
    at /home/me/temp/string_seg_test/src/MyObject.hpp:39
#2  0x0000000000401b7f in MyObject::resetProp2 (this=0x7fffffffe11000)
    at /home/me/temp/string_seg_test/src/MyObject.hpp:42
#3  0x000000000040197b in MyObject::MyObject (this=0x7fffffffe11000, parent=0x0)
    at /home/me/temp/string_seg_test/src/MyObject.hpp:21
#4  0x000000004017ee00 in ?? ()
#5  0x007fffffffe23800 in ?? ()
#6  0x0000010040154b00 in ?? ()
#7  0x000000004021b000 in ?? ()
#8  0x000000007ef92000 in ?? ()
#9  0x000000007ef9b000 in ?? ()
#10 0x0000000060310000 in ?? ()
#11 0x007ffff7d9a9d000 in ?? ()
#12 0x00000000604d2000 in ?? ()
#13 0x007fffffffe23000 in ?? ()
#14 0x0000000000000000 in ?? ()
(gdb) 
// Step N-1
#include <QString>
class C {
    QString m_prop1, m_prop2;
public:
    C() { setProp1("reset"); setProp2("reset"); }
    QString setProp1(const QString& prop1) { m_prop1 = prop1; }
    QString setProp2(const QString& prop2) { m_prop2 = prop2; }
} c;
int main(int, char **) {
    return 0;
}

// Step N
#include <QString>
class C {
    QString m_prop1;
public:
    C() { setProp1("reset"); setProp1("reset"); }
    QString setProp1(const QString& prop1) { m_prop1 = prop1; }
} c;
int main(int, char **) {
    return 0;
}