PDA

View Full Version : How to avoid implicit sharing of QString ?



marcvanriet
19th August 2011, 02:23
Hi,

I have a strange crash in a small app of mine, and I could trace it back to something I believe is related to implicit sharing of a QString.

This is sort of what happens :
- i receive a text message over TCP/IP
- this message is parsed using QJSON
- a value of a certain field is taken from the QJSON output as a QString
- this value is shown in a QLineEdit using setText()

Now, when the same value is written twice to the QLineEdit, a crash occurs.

This is my stack trace :

0 DbgBreakPoint ntdll 0x7c90120e
1 RtlpNtMakeTemporaryKey ntdll 0x7c96f26e
2 RtlValidateHeap ntdll 0x7c962fe0
3 HeapValidate kernel32 0x7c85f9a7
4 CrtIsValidHeapPointer MSVCR80D 0x102115ba
5 free_dbg MSVCR80D 0x102107a6
6 free_dbg MSVCR80D 0x1021065e
7 free MSVCR80D 0x102105de
8 qFree qmalloc.cpp 60 0x4ab8bd
9 QString::free qstring.cpp 1108 0x5135bf
10 QString::~QString qstring.h 869 0x47bff3
11 QLineControl::internalSetText qlinecontrol.cpp 637 0x655d3349
12 QLineControl::setText qlinecontrol_p.h 577 0x65560b07
13 QLineEdit::setText qlineedit.cpp 384 0x655caa06

So the crash is really inside Qt's internal functions. The crash does NOT occur if I first copy the value to another string and modify it (e.g. when I do toUpper()). But when I just copy the string, or when the original is already uppercase, then the crash occurs. This shows to me that the problem only occurs when the value written to the QLineEdit is an implicit copy of something else.


The quick-and-dirty solution so that I can move on with the program is to make a copy of the string that is not implicitely shared. But is there a way to do that ?

Regards,
Marc

wysota
19th August 2011, 02:48
Implicit sharing doesn't cause crashes. It's likely you are using threads or something else that causes the crash and it only manifests itself inside QString code.

marcvanriet
19th August 2011, 03:05
Hi Wysota,

I'm not using threads.

My packet handling routine is called from within the ReadyRead() signal of the client connection, and this one is created by the TCP server ( I get it using nextPendingConnection() ). The TCP server is created with my main dialog as its parent, so all its events and those of the connections it creates should be processed by the main event loop I think.

Right now I'm just looking for a workaround, so I can test the rest of my application, and deal with the real problem later on.

Regards,
Marc

Santosh Reddy
19th August 2011, 05:36
- a value of a certain field is taken from the QJSON output as a QString
- this value is shown in a QLineEdit using setText()
Could you post a some code related to above steps, I guess the problem might be there, also how do you set the text, is it using a signal/slot or a direct call?

wysota
19th August 2011, 08:48
Aren't you passing pointers to strings anywhere?

marcvanriet
19th August 2011, 12:41
Hi,

Unfortunately everything is part of a rather complicated project, so it is not easy to just give a piece of code. I would have to further isolate the problem (which I'll do shortly).

The TCP packet is first received and passed on as a QByteArray, and everything is passed on 'by reference' (which is internally a pointer indeed, but I don't do any 'pointer magic' or casting). The QByteArray is read by QJson and the value of a certain field is returned as QString. Then this QString is passed on by value to my function that sets the text in the QLineEdit.

Anyway, this code has been working before, so I'm sure it's just something silly somewhere, but I need to focus on other parts of the program right now. So I'd just like a quick workaround at this point.

Regards,
Marc

wysota
19th August 2011, 13:53
As I said, the fact that the fault manifests itself in here doesn't mean the fault is actually here. You might be chasing ghosts.

marcvanriet
20th August 2011, 02:03
Hi,

I rebuilt everything from source (including the QJSon library) and everything works fine now. It had probably to do with the fact that the QJson library was build a long time ago and maybe with a different Qt version as the one I'm using now.

Santosh, Wysota, thanks for the replies anyway.

Still, I would have liked to know how you can make a 'deep copy' of a string or other object that uses implicit sharing behind the scenes.

Regards,
Marc

wysota
20th August 2011, 09:56
You can call detach() method on the string (it's an undocumented method but it's there).