Results 1 to 5 of 5

Thread: Why does this crash (compilable code included)?

  1. #1
    Join Date
    Jul 2009
    Posts
    26
    Thanks
    2
    Qt products
    Qt4 Qt/Embedded
    Platforms
    MacOS X Windows

    Default Why does this crash (compilable code included)?

    Hello All,

    probably this is a simple question, however (maybe due to being tired) I cannot see any solution. The code below is extracted and simplified part of my application (these are some factory methods, basing on xml input). However now it magically(?) crashes on something else, than my original application. But still, maybe the reason is the same.

    I put both parts in main.cpp file. Hovewer originally have separated declarations and definitions.

    Two classes used are as follows:
    Qt Code:
    1. #include <QBitArray>
    2. #include <QDebug>
    3.  
    4. //! Base class, with one pure virtual method doActionThatCrashes()
    5. class PropertyConverter {
    6. public:
    7. virtual ~PropertyConverter(){}
    8. virtual void doActionThatCrashes() = 0;
    9. };
    10.  
    11. //! Inherits PropertyConverter and implements funciton that really crashes.
    12. class PropertyBitmaskConverter:
    13. public PropertyConverter
    14. {
    15. public:
    16. PropertyBitmaskConverter(QBitArray &mask):
    17. _bitmaskFromInternal(mask) {}
    18.  
    19. const QBitArray &mask(){return _bitmaskFromInternal;}
    20.  
    21. virtual void doActionThatCrashes();
    22.  
    23. private:
    24. const QBitArray &_bitmaskFromInternal;//!\warning Edit, thanks to d_stranz: That was an error in this code, since reference to stack variable was being copied. Remvoe ampresand.
    25. };
    26.  
    27. void PropertyBitmaskConverter::doActionThatCrashes() {
    28. QBitArray array = this->mask();
    29. int size = array.size();
    30. qDebug()<<"The number of bits is"<<size;
    31. }
    To copy to clipboard, switch view to plain text mode 
    And the code itself is:
    Qt Code:
    1. PropertyConverter *createPropertyConverter();
    2. QBitArray bitArrayFromString(QString &array, bool *ok);
    3. QBitArray bitArrayFromChar(const char *data, int size, bool *ok);
    4.  
    5.  
    6. int main(int argc, char *argv[])
    7. {
    8. PropertyConverter *bitmaskConverter = createPropertyConverter();
    9. if (0 != bitmaskConverter) {
    10. //! \note Here it DOES crash
    11. bitmaskConverter->doActionThatCrashes();
    12. }
    13.  
    14. return 0;
    15. }
    16.  
    17. PropertyConverter *createPropertyConverter()
    18. {
    19. bool ok;
    20. QString mask = "b'11101'";
    21. QBitArray bitMask;
    22. if (!mask.isEmpty())
    23. bitMask = bitArrayFromString(mask, &ok);
    24. if (!ok || bitMask.isNull())
    25. return 0;
    26.  
    27. PropertyConverter *bitmaskConverter = new PropertyBitmaskConverter(bitMask);
    28.  
    29. //! \note Here this doesn't crash
    30. bitmaskConverter->doActionThatCrashes();
    31.  
    32. return bitmaskConverter;
    33. }
    34.  
    35. QDebug operator<<(QDebug dbg, const QBitArray& z)
    36. {
    37. QString text;
    38. for (int i = 0; i < z.size(); ++i)
    39. text.prepend(z.testBit(i) ? "1": "0");
    40. dbg << text;
    41. return dbg;
    42. }
    43.  
    44. QBitArray bitArrayFromString(QString &array, bool *ok)
    45. {
    46. return bitArrayFromChar(array.toLatin1().data(), array.size(), ok);
    47. }
    48.  
    49. QBitArray bitArrayFromChar(const char *data, int size, bool *ok)
    50. {
    51. if (0 != ok)
    52. *ok = true;
    53.  
    54. if ( ((strncmp(data, "B'", 2) == 0) || (strncmp(data, "b'", 2) == 0)) &&
    55. data[size - 1] == '\'') {
    56. const int significantDataSize = size - 3;
    57. QBitArray result(significantDataSize, false);
    58. const char *bitPtr = &data[2];
    59. for (int i = significantDataSize - 1; i >= 0; --i) {
    60. if (*bitPtr == '1')
    61. result.setBit(i, true);
    62. ++bitPtr;
    63. }
    64. return result;
    65. } else
    66. if (0 != ok) *ok = false;
    67.  
    68. return QBitArray();
    69. }
    To copy to clipboard, switch view to plain text mode 

    In the code attached the crash occurs on the streaming by QDebug, in the doActionThatCrashes(). When doActionThatCrashes() is called inside createPropertyConverter it works fine. When it's called one stack call higher (in the main() function), on the same object (same virtual call) it does nasty things.

    In original application, the crash occurs on the array.size() call in PropertyConverter::doActionThatCrashes(). Please, if anyone could help me with this problem, I would be very glad. It stops me from further development and my fine grade

    Best regards,
    Krzysztof

    Edit: Oh, I almost forgot. This could be important. I am using Qt 4.7.4 (64bit) on Linux (Ubuntu).
    Last edited by Krzysztow; 6th December 2011 at 21:37.

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,161
    Thanks
    296
    Thanked 858 Times in 845 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Why does this crash (compilable code included)?

    In line 21, you create a QBitArray on the stack. You then store a reference to that QBitArray inside your class. As soon as the createPropertyConverter method exits, that QBitArray goes out of scope and is destroyed, but your PropertyBitmaskConverter is still holding onto a reference to it. Kaboom!

  3. #3
    Join Date
    Jul 2009
    Posts
    26
    Thanks
    2
    Qt products
    Qt4 Qt/Embedded
    Platforms
    MacOS X Windows

    Default Re: Why does this crash (compilable code included)?

    Quote Originally Posted by d_stranz View Post
    In line 21, you create a QBitArray on the stack. You then store a reference to that QBitArray inside your class. As soon as the createPropertyConverter method exits, that QBitArray goes out of scope and is destroyed, but your PropertyBitmaskConverter is still holding onto a reference to it. Kaboom!
    Thank You for You input. However I disagree with You, maybe I'm wrong. Here is my reasoning...
    Ok, QBitArray in 21st line is on stack. However its shared data gets created on heap. In the 27th line I pass a reference to the PropertyBitmaskConverter constructor, but in initialization list, calling _bitmastFromInternal(mask) means calling copy constructor of QBitArray (line 17th of the first code part). And, according to docs - it "constructs a copy of other". So when getting out of the function, mask is deleted, but shared data reference count is still non-zero, so this one stays and is kept for _bitmaskFromInternal member of PropertyBitmaskConver. So it doesn't go out of scope. Am I right?

    Anyway thanks. If I am wrong, please correct me.

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,161
    Thanks
    296
    Thanked 858 Times in 845 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Why does this crash (compilable code included)?

    but in initialization list, calling _bitmastFromInternal(mask) means calling copy constructor of QBitArray
    Wrong. All you are doing is storing a reference to the QBitArray, because your member variable (_bitmaskFromInternal) is also a reference. If you want to make a copy, declare _bitmaskFromInternal as a QBitArray, not a QBitArray &.

  5. The following user says thank you to d_stranz for this useful post:

    Krzysztow (6th December 2011)

  6. #5
    Join Date
    Jul 2009
    Posts
    26
    Thanks
    2
    Qt products
    Qt4 Qt/Embedded
    Platforms
    MacOS X Windows

    Default Re: Why does this crash (compilable code included)?

    Quote Originally Posted by d_stranz View Post
    Wrong. All you are doing is storing a reference to the QBitArray, because your member variable (_bitmaskFromInternal) is also a reference. If you want to make a copy, declare _bitmaskFromInternal as a QBitArray, not a QBitArray &.
    Damn it, You are right! My bad. I meant this ampresand go to const QBitArray &PropertyBitmaskConverter::mask() method. I overlooked it, when trying o simplify my class. Yeah, I normally know that. And moreover, I don't have this error in my original class :/ So my problem still exists. But this code compiles fine now...

    Thanks alot!

    Edit: d_stranz, thank You even more! You know what? I did the same error in my code. I was so sure I haven't made such a mistake, that I was traversing hundreds of lines in search of other reason. And here it was. The thing is, I never store class references, not my style. In classes I use pointers I must really be tired.
    Anyway, thank You so much! I can get back to work now.
    Last edited by Krzysztow; 6th December 2011 at 21:54. Reason: Another code revision

Similar Threads

  1. Replies: 0
    Last Post: 2nd February 2010, 05:38
  2. Release ok, debug crashes [compilable code]
    By Raccoon29 in forum Qt Programming
    Replies: 8
    Last Post: 16th December 2009, 16:48
  3. QTest dir not included by qmake
    By allstar in forum Qt Programming
    Replies: 1
    Last Post: 20th June 2007, 12:10
  4. header files not getting included
    By nimmyj in forum Installation and Deployment
    Replies: 1
    Last Post: 19th December 2006, 07:18
  5. Displaying picture included with html code
    By Djony in forum Qt Tools
    Replies: 1
    Last Post: 27th November 2006, 17:15

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.