Нарушение прав чтения при создании QDomElement во второй раз

Я написал класс для обработки файла XML. Класс загружает файл при построении и сохраняет его при уничтожении. Пока класс активен, у меня есть несколько функций получения и установки для изменения значений. Одной из них является функция регистрации некоторых переименований файлов. При каждом вызове он создает новый дочерний элемент для elem_renames.

void DataElementHandle::renamed(QString new_name, QString old_name)
{
QDomElement elem_ren = xml_doc.createElement("renamed");
QDomAttr att = xml_doc.createAttribute("time");
att.setValue(QDateTime::currentDateTime().toString(Qt::ISODate));
elem_ren.setAttributeNode(att);

QDomText t = xml_doc.createTextNode(old_name + " -> " + new_name);
elem_ren.appendChild(t);

elem_renames.appendChild(elem_ren);
}

Проблема: Теперь я создаю класс DataElementHandle и вызываю функцию переименования для каждого изменения в файлах. Но каждый второй раз, когда я вызываю функцию, моя программа падает с этим сообщением об ошибке:

Исключение: нарушение прав на чтение.
Ошибка выдается в первой строке функции.

Я не понимаю, почему это происходит. Я думаю, что не могу переопределить QDomElement, потому что все еще есть ссылка на элемент, созданный при первом вызове. Но как? Это должно быть в конце функции.

Я использую Qt 5.8 с Visual Studio 2015 и Visual Leak Detector.

Заголовочный файл:

// Version
const quint32 version = 1;

// Doc file path
QString file_path;
bool load_file_ok;

// Doc
QDomDocument xml_doc;
QDomElement root;

// First root elements
QDomElement elem_renames;

Если файл XML не существует, создается новый шаблон, подобный этому, и он будет сохранен в файле в деструкторе.

xml_doc = QDomDocument("data_xml");
root = xml_doc.createElement("root");
root.setAttribute("version", QString::number(version));
xml_doc.appendChild(root);

elem_renames= xml_doc.createElement("renames");

root.appendChild(elem_renames);

Изменить 1: Я настроил тестовый проект, и там он отлично работает. Я должен исследовать проблему более подробно.

0

Решение

Решено!
Я такой глупый. У меня была такая настройка. И я объявил и инициализировал указатель на класс XML в цикле for. И так как я удаляю старый и создаю новый класс в операторе if ниже, я инициализировал указатель в операторе if в первый раз, но затем удалил его во втором.

#include <QCoreApplication>
#include <QDomDocument>
#include <QFile>
#include <QDateTime>
#include <QString>
#include <QDebug>

class TestDomClass
{
public:
TestDomClass(QString file_path) :
path(file_path)
{
xml_doc = QDomDocument("data_xml");
root = xml_doc.createElement("root");
root.setAttribute("version", QString::number(version));
xml_doc.appendChild(root);

elem_renames= xml_doc.createElement("renames");

root.appendChild(elem_renames);
}
~TestDomClass()
{
QFile file(path);
if(!file.open(QIODevice::WriteOnly | QIODevice::Text))
{
// TODO
qDebug() << "Failed to open file for writing!";
}
else
{
QTextStream stream(&file);
stream << xml_doc.toString();
}

if(file.isOpen())
{
file.close();
}
}

void renamed(QString new_name, QString old_name)
{
QDomElement elem_ren = xml_doc.createElement("renamed");
QDomAttr att = xml_doc.createAttribute("time");
att.setValue(QDateTime::currentDateTime().toString(Qt::ISODate));
elem_ren.setAttributeNode(att);

QDomText t = xml_doc.createTextNode(old_name + " -> " + new_name);
elem_ren.appendChild(t);

elem_renames.appendChild(elem_ren);
}

private:
QString path;

// Version
const quint32 version = 1;

// Doc
QDomDocument xml_doc;
QDomElement root;

// First root elements
QDomElement elem_renames;
};

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

TestDomClass *t = Q_NULLPTR; // <-- This line was in the for loop

for(int a = 0; a < 10; ++a)
{
delete t;
t = new TestDomClass("test_" + QString::number(a) + ".xml");
for(int i = 0; i < 10; ++i)
{
qDebug() << "Round: " << i;
t->renamed(QString::number(10*a + i), QString::number(10*a + 10-i));
}
}

delete t;

return a.exec();
}
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]