2017-11-20 3 views
0

XMLファイルを処理するためのクラスを作成しました。クラスは構築中のファイルをロードし、破壊時にファイルを保存します。クラスがアクティブな間、私は値を変更するいくつかのゲッターとセッター関数を持っています。そのうちの1つは、ファイルの名前の変更を記録する機能です。各呼び出しで、elem_renamesの新しい子要素が作成されます。2回目にQDomElementを作成する読み取りアクセス違反

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クラスを作成し、ファイルへの変更ごとにrename関数を呼び出します。しかし、私はこのエラーメッセージで私のプログラムがクラッシュする関数を呼び出します:

例外がスローされました:読み取りアクセス違反。 エラーは、関数の最初の行にスローされます。

なぜこのようなことが起こるのかわかりません。最初の呼び出しで作成された要素へのリンクがまだ存在するため、QDomElementをオーバーライドできないと思います。しかしどうですか?それは機能の終わりになくなっているはずです。

Visual Studio 2015とVisual Leak DetectorでQt 5.8を使用します。

ヘッダファイル:

// 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:私はテストプロジェクトを設定して、そこにそれが正常に動作します。私は問題をより詳細に調査しなければならない。

答えて

2

解決済み! 私はとても愚かです。私はこのような設定をしていました。そして、私は宣言し、forループのXMLクラスへのポインタを初期化しました。そして、古いものを削除し、以下のif文で新しいクラスを作成するので、if文の中でポインタを最初に初期化しましたが、2番目に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(); 
} 
関連する問題