PDA

View Full Version : QDomElement::text() returns corrupted strings



sladecek
7th March 2009, 09:39
Hi,

please explain what is wrong with my code:


#include <QDomDocument>
#include <QFile>

int main(int argc, char *argv[])
{

QDomDocument doc;
QFile file("c:\\bugtest.xml");
file.open(QIODevice::ReadOnly);
doc.setContent(&file);
file.close();

QDomElement docElem = doc.documentElement();

QDomNode n = docElem.firstChild();
while(!n.isNull()) {
QDomElement e = n.toElement(); // try to convert the node to an element.
if(!e.isNull()) {
if (e.tagName() == "value" && e.hasAttribute("id"))
{
QString id = e.attribute("id");
QString data = e.text();
} /* crash point */
n = n.nextSibling();
}
}
}

The code crashes at the point marked, when deleting QString data - heap corrupted.

The document is:

<?xml version="1.0" encoding="utf-8"?>
<data>
<value id="some_id">Some value</value>
</data>

Windows XP, Visual studio 2005, QT 4.5.0-rc1 (also 4.3.5).


Thanks in advance.

roxton
7th March 2009, 10:22
As far I see, you need to implement a recursive XML-tree walker, because yours one cannot reach the "value" element.



void step (QDomNode node)
{
for (QDomNode n = node.firstChild(); ! n.isNull(); n = n.nextSibling())
{
QDomElement e = n.toElement();

if (e.isNull())
continue;

if (e.nodeName().toLower() == "value")
{
QString id = e.attribute ("id");

if (! id.isEmpty())
{
QString data = e.text(); //good
}

}

if (e.hasChildNodes())
step (n);
}
}

//and use it:

step (doc.documentElement());

sladecek
7th March 2009, 11:07
Thank you for your answer.

Unfortnatelly, Your code fails in the same way as mine.

HEAP[visu000.exe]: Invalid Address specified to RtlValidateHeap( 003D0000, 00BE7260 )
Windows has triggered a breakpoint in visu000.exe.

This may be due to a corruption of the heap, and indicates a bug in visu000.exe or any of the DLLs it has loaded.

The output window may have more diagnostic information
The program '[1532] visu000.exe: Native' has exited with code 0 (0x0).


My code can read the value . The string data contains "Some value" as expected. But when the QString "data" is about to be deleted and the destructor is called the program crashes due to heap corruption.

wysota
7th March 2009, 12:25
Is this the exact code that crashes? It seems to work fine for me. If it's part of some larger application, please provide some background information (like if you use threads or not) or a compilable example reproducing the problem.

sladecek
7th March 2009, 12:43
Thank you for testing my code.

Yes, exactly this code crashes. Moreover, I tried the SAX API in meantime and it crashes too:



class Parser: public QXmlDefaultHandler;

bool Parser::characters ( const QString & ch )
{
m_cData.append(ch); // crash
return true;
}


I use the free version of QT compiled from source by MS VC++. Maybe the Qt XML library was compiled badly?

wysota
7th March 2009, 12:53
Maybe. Do examples bundled with Qt work? Also, when it crashes try debugging to see where the crash occurs.

sladecek
7th March 2009, 14:07
Thank you for you effort.

Problem solved. Wrong library name in library inputs. I linked with QtXml4.lib instead of correct QtXmlD4.lib.