Crash with LinkEndChild for _Not_ FirstChild

2009-09-21
2013-05-20
  • Peter le Roux
    Peter le Roux
    2009-09-21

    Hello.

    when i try to use LinkEndChild to add an element to a tag other than the FirstChild, my app crashes inside LinkEndChild.  this happend consistently, and it consistently does not crash when i am attempting to add an element to the FirstChild.

    I will attach the function i use to do that.  I'm expecting that the OtherThan FirstChild (i'm using NextSibing("") to iterate) doesn't link in the same way ??

    I can make an app to illustrate the crash by calling this function to add anything to a 2nd or 3rd etc. tag on something other than the first child, or send you my app skeleton i'm making and runtime "how to reproduce".  i Would gladly send it to you, but can't see where to do that…

    I'm using WinXP SP3 with Bloodshed Dev c++  v4.9.9.2

    my sourceforge USN is p3tr, but i will come back and check next week or so for a reply.

    regards
    peter

    Here Follows Function:

    {

    bool AddNode(string Path, string Value, string NodeName, string NodeValue, int Depth, string AttName, string Attribute){

    bool bSuccess = true;
    bool IsFirst = true;
    TiXmlDocument doc(DbFile.c_str());
    if(!doc.LoadFile()){
    cout<<"\nCouldn't Load "<<DbFile<<endl;
    return false;
    }
    TiXmlHandle hDoc(&doc);
    TiXmlElement* pElem;//Working Element (Sibling to What we're Adding)
    TiXmlHandle hRoot(0);
    TiXmlElement* oElem;//Original Element (adding Child to This Level)

    // block: name
    {
    oElem=hDoc.FirstChildElement(RootNode.c_str()).Element();
    // should always have a valid root but handle gracefully if it does
    if (!oElem){
    cout<<"RootNode "<<RootNode<<" Not Found in "<<DbFile<<endl;
    doc.SaveFile(DbFile.c_str());
    return false;
    }
    // save this for later
    hRoot=TiXmlHandle(oElem);
    }

    //Block: Iterative Mounting… (Do when we have an example) - Copied from Listnode (since it does the same thing…)
    {
    for(int i = 0; i < Depth; ++i){
    oElem = hRoot.FirstChildElement(Path_.c_str()).Element();
    if(oElem){
    string pText = oElem->GetText();
    if(pText == Value){
    hRoot = TiXmlHandle(oElem);
    }
    else{
    while(oElem){
    oElem=oElem->NextSiblingElement(Path.c_str());
    if(oElem){
    pText=oElem->GetText();
    if(pText == Value){
    hRoot=TiXmlHandle(oElem);
    IsFirst = false;
    }
    }
    }
    }
    }
    else{
    cout<<"No "<<Path<<" Found in "<<DbFile<<endl;
    doc.SaveFile();
    return false;
    }
    }
    }

    // block: string table
    {
    pElem = hRoot.FirstChildElement(NodeName.c_str()).Element();
    if(pElem){
    string pText=pElem->GetText();
    if(pText == NodeValue){
    cout<<NodeName<<" Called "<<NodeValue<<" Already Exists…"<<endl;
    doc.SaveFile(DbFile.c_str());
    return false;
    }
    while(pElem){
    pElem=pElem->NextSiblingElement(NodeName.c_str());
    if(pElem){
    pText=pElem->GetText();
    if(pText == NodeValue){
    cout<<NodeName<<" Called "<<NodeValue<<" Already Exists…"<<endl;
    doc.SaveFile(DbFile.c_str());
    return false;
    }
    }
    }
    }
    }

    //So now we know the Node / Value set does not exist yet… (and we can write it to the file)
    TiXmlElement * MyElement = new TiXmlElement(NodeName.c_str());
    TiXmlText * NewText = new TiXmlText(NodeValue.c_str());

    //Linked my Element Together…
    MyElement->LinkEndChild(NewText);

    if(AttName != ""){
    MyElement->SetAttribute(AttName.c_str(), Attribute.c_str());
    }

    //Links This Node to the Root of the WorkingNode…
    oElem->LinkEndChild(MyElement);

    //*/

    doc.SaveFile(DbFile.c_str());
    return bSuccess;
    }

    }_

     
  • Peter le Roux
    Peter le Roux
    2009-09-21

    OK never mind, I'm an idiot…

    I keep moving the RootNode even when i don't change the oElem handle.

    Attached is the Updated function WHICH WORKS.
    So I'm very happy.  Thanks for a really cool piece of code which does realy cool things for me…

    And sorry for getting everyone in a state and writing stuff about a crash.

    Here Follows:

    {

    bool AddNode(string Path, string Value, string NodeName, string NodeValue, int Depth, string AttName, string Attribute){

    bool bSuccess = true;
    bool IsFirst = true;
    TiXmlDocument doc(DbFile.c_str());
    if(!doc.LoadFile()){
    cout<<"\nCouldn't Load "<<DbFile<<endl;
    return false;
    }
    TiXmlHandle hDoc(&doc);
    TiXmlElement* pElem;//Working Element (Sibling to What we're Adding)
    TiXmlHandle hRoot(0);
    TiXmlElement* oElem;//Original Element (adding Child to This Level)

    // block: name
    {
    oElem=hDoc.FirstChildElement(RootNode.c_str()).Element();
    // should always have a valid root but handle gracefully if it does
    if (!oElem){
    cout<<"RootNode "<<RootNode<<" Not Found in "<<DbFile<<endl;
    doc.SaveFile(DbFile.c_str());
    return false;
    }
    // save this for later
    hRoot=TiXmlHandle(oElem);
    }

    //Block: Iterative Mounting… (Do when we have an example) - Copied from Listnode (since it does the same thing…)
    {
    for(int i = 0; i < Depth; ++i){
    oElem = hRoot.FirstChildElement(Path_.c_str()).Element();
    if(oElem){
    string pText = oElem->GetText();
    if(pText == Value){
    hRoot = TiXmlHandle(oElem);
    }
    else{
    while(pText != Value){
    oElem=oElem->NextSiblingElement(Path.c_str());

    if(oElem){
    pText=oElem->GetText();
    if(pText == Value){
    hRoot=TiXmlHandle(oElem);
    IsFirst = false;
    }
    }

    }
    }
    }
    else{
    cout<<"No "<<Path<<" Found in "<<DbFile<<endl;
    doc.SaveFile();
    return false;
    }
    }
    }

    // block: string table
    {
    pElem = hRoot.FirstChildElement(NodeName.c_str()).Element();
    if(pElem){
    string pText=pElem->GetText();
    if(pText == NodeValue){
    cout<<NodeName<<" Called "<<NodeValue<<" Already Exists…"<<endl;
    doc.SaveFile(DbFile.c_str());
    return false;
    }
    while(pElem){
    pElem=pElem->NextSiblingElement(NodeName.c_str());
    if(pElem){
    pText=pElem->GetText();
    if(pText == NodeValue){
    cout<<NodeName<<" Called "<<NodeValue<<" Already Exists…"<<endl;
    doc.SaveFile(DbFile.c_str());
    return false;
    }
    }
    }
    }
    }

    //So now we know the Node / Value set does not exist yet… (and we can write it to the file)
    TiXmlElement * MyElement = new TiXmlElement(NodeName.c_str());
    TiXmlText * NewText = new TiXmlText(NodeValue.c_str());

    //Linked my Element Together…
    MyElement->LinkEndChild(NewText);

    if(AttName != ""){
    MyElement->SetAttribute(AttName.c_str(), Attribute.c_str());
    }

    //Links This Node to the Root of the WorkingNode…
    oElem->LinkEndChild(MyElement);

    doc.SaveFile(DbFile.c_str());
    return bSuccess;
    }

    }_