Qt QXmlStreamReader Access Violation
Qt QXmlStreamReader Access Violation
我正在使用Qt 5.11.1(MSVSC2015 32位(和QtCreator 4.6.2。 我在使用 QXmlStreamReader 解析 XML 时遇到问题。代码是基于Qt的例子编写的。 当我的代码被执行时,它会在 QIODevice 中产生访问冲突.cpp在 checkWarnMessage 函数中。 此图显示了发生访问冲突的调用堆栈和确切行。
实际的 XML i 更复杂,并且具有嵌套元素。解析XML的函数的实现方式与Qt示例中的void XbelReader::readXBEL((函数相同(基于元素名称调用适当的函数来解析该元素(。但是通过这个简单的例子,我设法重现了我在实际解决方案中遇到的问题。
XML 是:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<element1>1</element1>
<element2>2</element2>
<element3>3</element3>
<element4>4</element4>
<element5>5</element5>
<element6>6</element6>
</root>
解析此 XML 的代码是:
#include <string>
#include <stdexcept>
#include <iostream>
#include <QCoreApplication>
#include <QXmlStreamReader>
#include <QFile>
#include <QString>
#define ASSERT_ELEMENT_NAME(NAME) Q_ASSERT(xmlReader.isStartElement() && xmlReader.name() == NAME);
using namespace std;
void OpenFile(const QString& fileName, QXmlStreamReader& xmlReader)
{
QFile configFile(fileName);
if (configFile.open(QFile::ReadOnly | QFile::Text) == false)
throw runtime_error(string("Failed to open file: ") + configFile.errorString().toStdString());
xmlReader.setDevice(&configFile);
if (xmlReader.readNextStartElement() == false)
throw runtime_error("File does not have root element");
if (xmlReader.name() != "root")
throw runtime_error("File has invalid root element");
}
void ParseElement1(QXmlStreamReader& xmlReader)
{
ASSERT_ELEMENT_NAME("element1");
auto text = xmlReader.readElementText().trimmed();
auto isOk = false;
auto value = text.toInt(&isOk);
if (isOk == false)
throw runtime_error(string("invalid value: ") + text.toStdString());
else
cout << "element1: " << value << endl;
}
void ParseElement2(QXmlStreamReader& xmlReader)
{
ASSERT_ELEMENT_NAME("element2");
auto text = xmlReader.readElementText().trimmed();
auto isOk = false;
auto value = text.toInt(&isOk);
if (isOk == false)
throw runtime_error(string("invalid value: ") + text.toStdString());
else
cout << "element2: " << value << endl;
}
int main()
{
QXmlStreamReader xmlReader;
OpenFile("config.xml", xmlReader);
while(xmlReader.readNextStartElement())
{
if(xmlReader.name() == "element1")
ParseElement1(xmlReader);
if(xmlReader.name() == "element2")
ParseElement2(xmlReader);
else
xmlReader.skipCurrentElement();
}
}
如果我在主函数中评论两行:
if(xmlReader.name() == "element2")
ParseElement2(xmlReader);
不会发生访问冲突。
我真的不知道我做错了什么。还是QXmlStreamReader中存在错误?我认为即使我做错了什么,Qt的库中也不应该发生访问冲突。
整个项目(XmlParser.pro、主.cpp和配置.xml(可以从此链接下载
编辑
我已经按照 Manthan 的建议修复了我的示例,它按预期工作。我在 XML 中添加了另一件事。我在元素 1 之前添加了大的多行注释。注释本身有 8019 个字符,包括空格字符,而整个 XML 文件有 8266 个字符。
XML 现在看起来像
<?xml version="1.0" encoding="UTF-8"?>
<root>
<!--
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, co
-->
<element1>1</element1>
<element2>2</element2>
<element3>3</element3>
<element4>4</element4>
<element5>5</element5>
<element6>6</element6>
</root>
我已经检查了XML在带有XML工具插件的Notepad ++中是否有效,并且在xmlvalidation.xml上也有效。当我使用新 XML 执行固定示例时,我再次在先前链接的图像上描绘的完全相同的位置上出现访问冲突。
现在,如果我从 XML 中的注释中删除最后一个"o"字符(或从注释中删除任何其他字符,或者从 element6 的文本中删除"6",或者事实上在保持 XML 有效的同时从 XML 中删除任何字符(,示例成功执行。这是我最初的问题。我在原始XML文件中有很多注释,导致文件大于8KB。目前,作为一种解决方法,我删除评论以避免访问冲突。
我不清楚注释(或文件(长度如何导致访问冲突。
整个项目可以从此链接下载
问题出在 while 循环中。更新如下。
while(xmlReader.readNextStartElement())
{
if(xmlReader.name() == "element1")
ParseElement1(xmlReader);
else if(xmlReader.name() == "element2")
ParseElement2(xmlReader);
else
xmlReader.skipCurrentElement();
}
在您的代码中,第一个元素的类型是"element1",然后首先它处理(带有第一个if
(,然后它们再次来到else
它试图跳过它的地方,这会导致问题。
- 将数组信息存储到 c++ 向量中有一个"Access violation reading location"
- 为什么调试器引发"read access violation. this was nullptr"异常?
- Simulink "Access Violation"写入 C++ lambda 函数捕获列表中的 PWork 变量
- Qt QXmlStreamReader Access Violation
- 指向 std::unrodered_map 中元素的指针返回'Read access violation'
- 例外:'Access violation reading location'
- 我在发布模式下运行时收到"Access violation reading location"错误 - C++
- 如何修复我的 c++ 毕达哥拉斯三重查找器中的'access violation reading location'错误?
- 矩阵 - "Access violation writing location 0x00900B0C" - C++ 中的错误
- 如何修复此代码中的'Access violation reading location'
- 过载时出错 << "Exception thrown: read access violation.m.matrix was 0xCDDDCDDE."
- c++:链表错误" Access violation reading location"
- Q维吉特"access violation"
- System.UStrClr Access Violation
- msftedit "Access violation reading location 0x00000008"错误.dll SetWindowSub类中的RichEdit控件
- CreateBuffer 抛出一个"Access violation reading location"
- glMapBufferRange Access Violation
- 指针已初始化,但我有错误"Access violation reading location 0xCCCCCCCC".为什么?
- VC++ vector::p ush_back "Access Violation" in DLL
- "Read Access Violation: This was nullptr" 以为我分配正确...?