mercredi 31 août 2016

Why is my program crashing when compiling in Release mode? [Visual Studio 2015]

I'm working on a server, and i need to load data.Part of data i need to load is written in xml files so i writen a basic XMLDocumentParser.

const byte XMLDocumentParser::ParseXMLDocument(std::vector<XMLNode*>& out_nodes, const char * fileName)
    {
        std::ifstream file = std::ifstream(fileName, std::ifstream::ate);
        if (!file.is_open())
            return 1;
        unsigned int fileSize = file.tellg();
        file.seekg(std::ifstream::beg);

        char * buffer = new char[fileSize];
        file.read((char*)buffer, fileSize);
        file.close();
        if (fileSize <= 80)
        {
            return 2; // nothing to read
        }

        XMLNode * newNode = nullptr;
        int mainCursor = 0;
        for (size_t i = 0; i < 2; i++)
        {
            newNode = new XMLNode();
            mainCursor += GetNode(buffer, mainCursor, newNode);
            if (newNode)
            {
                out_nodes.push_back(newNode);
            }
        }


        delete[] buffer;
        buffer = 0;
        return 0;
    }

and the main recursive function

 int XMLDocumentParser::GetNode(char* buffer, int mainCursor, XMLNode* outNode)
{
    int argumentCursor = 0, valueCursor = 0, nameCursor = 0; byte result = 0;
    short argumentNameSize = 0, argumentValueSize = 0, nameSize;
    char* name = 0;


#pragma region NAME
    while (1)
    {
        if (buffer[mainCursor] == '<')
        {
            mainCursor++;

            while (buffer[mainCursor] == ' ')
                mainCursor++; //remove whiteSpaces

            nameCursor = mainCursor;

            while (buffer[nameCursor] != ' ' && buffer[nameCursor] != '>')
                nameCursor++;
            nameSize = nameCursor - mainCursor;
            if (nameSize <= 0)
            {
#ifdef XML_DEBUG
                result = 3;
                std::cout << "::NAME SIZE IS [" << nameSize << "] LINE[" << __LINE__ << "] ->ERROR\n\n";
#endif
                break;
            }

            name = new char[nameSize + 1];
            if (memcpy((void*)name, (const void*)&buffer[mainCursor], nameSize) == 0)
            {
#ifndef XML_DEBUG
                result = 4;
                std::cout << "::NAME MEMCPY FAILED NAMESIZE[" << nameSize << "] MAINCURRSOR[" << mainCursor << "] NAMECURSOR[" << nameCursor << "] ERROR\n\n";
#endif
                break;
        }
            mainCursor += nameSize;
            name[nameSize] = '\0';
            break;
    }
        mainCursor++;
}
#pragma endregion
    outNode->tagName = name;

    while (buffer[mainCursor] == ' ')
        mainCursor++; //remove whiteSpaces

    if (name[0] == '/')
        return mainCursor;

    //case <tagname> or <tagname/>
    if (buffer[mainCursor] == '/' && buffer[mainCursor + 1] == '>')
    {
        mainCursor += 2; //go past />
        return mainCursor;
    }
    else if (buffer[mainCursor] == '>')
    {
        XMLNode* childNode = nullptr;
        while (1)
        {
            childNode = new XMLNode();
            childNode->parentNode = outNode;
            mainCursor = GetNode(buffer, mainCursor, childNode);
            outNode->childNodes.push_back(childNode);
            char* toCheckName = new char[strlen(name) + 2];
            toCheckName[0] = '/';
            memcpy((void*)&toCheckName[1], (const void*)name, strlen(name) + 1);
            if (strcmp((const char*)toCheckName, (const char*)childNode->tagName) == 0)
            {
                delete[] toCheckName;
                toCheckName = 0;
                break;
            }
            delete[] toCheckName;
            toCheckName = 0;
        }
        return mainCursor;
    }

#pragma region ARGUMENTS
    while (1)
    {
        while (buffer[mainCursor] == ' ')
            mainCursor++; //remove whiteSpaces

        if (buffer[mainCursor] == '>') // node with no arguments
        {
            argumentCursor++; // go past >
            XMLNode* childNode = nullptr;
            while (1)
            {
                childNode = new XMLNode();
                childNode->parentNode = outNode;
                argumentCursor = GetNode(buffer, argumentCursor, childNode);
                outNode->childNodes.push_back(childNode);
                char* toCheckName = new char[strlen(name) + 2];
                toCheckName[0] = '/';
                memcpy((void*)&toCheckName[1], (const void*)name, strlen(name) + 1);
                if (strcmp((const char*)toCheckName, (const char*)childNode->tagName) == 0)
                {
                    delete[] toCheckName;
                    toCheckName = 0;
                    break;
                }
                delete[] toCheckName;
                toCheckName = 0;
            }

            mainCursor = argumentCursor;
            break;
        }
        else if (buffer[mainCursor] == '/' && buffer[mainCursor] == '>')
        {
            break;// no arguemtns , node finished
        }


        XMLNodeArgument * newArg = new XMLNodeArgument();
        valueCursor = 0; argumentCursor = mainCursor;


        while (1)
        {
            if (buffer[argumentCursor] == '\"' && valueCursor == 0)
            {
                if (buffer[argumentCursor + 1] == '\"') //case argName=""
                {
                    argumentCursor++;
                    valueCursor = argumentCursor;
                    argumentCursor++;
                    break;
                }

                argumentCursor++;
                valueCursor = argumentCursor;

            }
            else if (buffer[argumentCursor] == '\"' && valueCursor != 0)
            {
                argumentCursor++;
                break;
            }

            argumentCursor++;
        }

        argumentValueSize = argumentCursor - valueCursor - 1;
        argumentNameSize = valueCursor - mainCursor - 2;

        newArg->argumentName = new char[argumentNameSize + 1];
        newArg->argumentValue = new char[argumentValueSize + 1];

        if (memcpy((void*)newArg->argumentName, (const void*)&buffer[mainCursor], argumentNameSize) == 0)
        {
#ifdef XML_DEBUG
            result = 1;
            std::cout << "ARGUMENT NAME FAILED ARGUMENTCURSOR[" << argumentCursor << "] ARGUMENTNAMESIZE[" << argumentNameSize << "] MAINCURSOR[" << mainCursor << "] buffer[MAINCURSOR]=" << buffer[mainCursor] << "]\n";
#endif
            break;
        }
        if (memcpy((void*)newArg->argumentValue, (const void*)&buffer[valueCursor], argumentValueSize) == 0)
        {
#ifdef XML_DEBUG
            result = 1;
            std::cout << "ARGUMENT VALUE FAILED ARGUMENTCURSOR[" << argumentCursor << "] ARGUMENTNAMESIZE[" << argumentNameSize << "] MAINCURSOR[" << mainCursor << "] buffer[MAINCURSOR]=" << buffer[mainCursor] << "]\nARGUMENTVALUESIZE[" << argumentValueSize << "] ARGUMENTCUROSR[" << argumentCursor << "]\n";
#endif
            break;
        }

        newArg->argumentName[argumentNameSize] = '\0';
        newArg->argumentValue[argumentValueSize] = '\0';

        outNode->_arguments.push_back(newArg);

        while (buffer[argumentCursor] == ' ')
            argumentCursor++;

        if (buffer[argumentCursor] == '>')
        {
            argumentCursor++; // go past >
            XMLNode* childNode = nullptr;
            while (1)
            {
                childNode = new XMLNode();
                childNode->parentNode = outNode;
                argumentCursor = GetNode(buffer, argumentCursor, childNode);
                outNode->childNodes.push_back(childNode);
                char* toCheckName = new char[strlen(name) + 2];
                toCheckName[0] = '/';
                memcpy((void*)&toCheckName[1], (const void*)name, strlen(name) + 1);
                if (strcmp((const char*)toCheckName, (const char*)childNode->tagName) == 0)
                {
                    delete[] toCheckName;
                    toCheckName = 0;
                    break;
                }
                delete[] toCheckName;
                toCheckName = 0;
            }

            mainCursor = argumentCursor;
            break;
        }
        else if (buffer[argumentCursor] == '/' && buffer[argumentCursor + 1] == '>')
        {
            //we dont have ChildNodes return size
            argumentCursor += 2; //go past />
            mainCursor = argumentCursor;
            return mainCursor;
        }
        else if (buffer[argumentCursor] == '?' && buffer[argumentCursor + 1] == '>')
        {
            //we dont have ChildNodes return size
            argumentCursor += 2; //go past />
            mainCursor = argumentCursor;
            return mainCursor;
        }
        mainCursor += argumentNameSize + argumentValueSize + 3;
    }
#pragma endregion
    return mainCursor;
    }

Then i use this function to get desired data out of XMLNodes

    void XMLDocumentParser::BuildItems(XMLNode * mainnode, std::vector<IItem*>& out_items)
{
    for (size_t j = 0; j < mainnode->childNodes.size() - 1; j++)
    {
        XMLNode* node = mainnode->childNodes[j];
        XMLNodeArgument* arg = nullptr;
        IItem* out = new IItem();
        for (size_t i = 0; i < node->_arguments.size(); i++)
        {
            if ((arg = node->ConsumeArgument("id")))
            {
                out->_id = atoi((const char*)arg->argumentValue);
            }
            else if ((arg = node->ConsumeArgument("name")))
            {
                out->_name = new char[strlen((const char*)arg->argumentValue)];
                strcpy((char*)out->_name, (const char*)arg->argumentValue);
            }
            else if ((arg = node->ConsumeArgument("coolTime")))
            {
                out->_coolTime = atoi((const char*)arg->argumentValue);
            }
            else if ((arg = node->ConsumeArgument("category")))
            {
                out->_category = itemCategoryDictionary[(const char*)arg->argumentValue];
            }
            else if ((arg = node->ConsumeArgument("level")))
            {
                out->_itemLevel = atoi((const char*)arg->argumentValue);
            }
            else if ((arg = node->ConsumeArgument("rank")))
            {
                out->_rank = atoi((const char*)arg->argumentValue);
            }
            else if ((arg = node->ConsumeArgument("maxStack")))
            {
                out->_maxStack = atoi((const char*)arg->argumentValue);
            }
            else if ((arg = node->ConsumeArgument("rareGrade")))
            {
                out->_rareGrade = (ItemRareGrade)atoi((const char*)arg->argumentValue);
            }
            else if ((arg = node->ConsumeArgument("requiredEquipmentType")))
            {
                out->_requiredEquipmentType = itemTypeDictionary[(const char*)arg->argumentValue];
            }
            else if ((arg = node->ConsumeArgument("combatItemType")))
            {
                out->_type = itemTypeDictionary[(const char*)arg->argumentValue];
            }
            else if ((arg = node->ConsumeArgument("requiredLevel")))
            {
                out->_requiredLevel = atoi((const char*)arg->argumentValue);
            }
            else if ((arg = node->ConsumeArgument("artisanable")))
            {
                out->_artisanable = ((const char*)arg->argumentValue) == "True" ? 1 : 0;
            }
            else if ((arg = node->ConsumeArgument("dismantlable")))
            {
                out->_dismantlable = ((const char*)arg->argumentValue) == "True" ? 1 : 0;
            }
            else if ((arg = node->ConsumeArgument("enchantEnable")))
            {
                out->_enchantEnabled = ((const char*)arg->argumentValue) == "True" ? 1 : 0;
            }
            else if ((arg = node->ConsumeArgument("extractLook")))
            {
                //todo
            }
            else if ((arg = node->ConsumeArgument("guildWarehouseStorable")))
            {
                out->_guildBankStorable = ((const char*)arg->argumentValue) == "True" ? 1 : 0;
            }
            else if ((arg = node->ConsumeArgument("masterpieceRate")))
            {
                out->_masterpieceRate = atof((const char*)arg->argumentValue);
            }
            else if ((arg = node->ConsumeArgument("obtainable")))
            {
                out->_obtainable = ((const char*)arg->argumentValue) == "True" ? 1 : 0;
            }
            else if ((arg = node->ConsumeArgument("sellPrice")))
            {
                out->_sellPrice = atoi((const char*)arg->argumentValue);
            }
            else if ((arg = node->ConsumeArgument("slotLimit")))
            {
                out->_slotLimit = atoi((const char*)arg->argumentValue);
            }
            else if ((arg = node->ConsumeArgument("sortingNumber")))
            {
                out->_sortingNumber = atoi((const char*)arg->argumentValue);
            }
            else if ((arg = node->ConsumeArgument("storeSellable")))
            {
                out->_sellable = ((const char*)arg->argumentValue) == "True" ? 1 : 0;
            }
            else if ((arg = node->ConsumeArgument("tradable")))
            {
                out->_tradable = ((const char*)arg->argumentValue) == "True" ? 1 : 0;
            }
            else if ((arg = node->ConsumeArgument("unidentifiedItemGrade")))
            {
                out->_itemGrade = (ItemGrade)atoi((const char*)arg->argumentValue);
            }
            else if ((arg = node->ConsumeArgument("useOnlyTerritory")))
            {
                out->_useOnlyTerritory = ((const char*)arg->argumentValue) == "True" ? 1 : 0;
            }
            else if ((arg = node->ConsumeArgument("warehouseStorable")))
            {
                out->_warehouseStoreable = ((const char*)arg->argumentValue) == "True" ? 1 : 0;
            }
            else if ((arg = node->ConsumeArgument("changeColorEnable")))
            {
                out->_changeColorEnable = ((const char*)arg->argumentValue) == "True" ? 1 : 0;
            }
            else if ((arg = node->ConsumeArgument("boundType")))
            {
                out->_bountType = itemBoundTypeDictionary[(const char*)arg->argumentValue];
            }
            else if ((arg = node->ConsumeArgument("requiredClass")))
            {
                out->_requiredClass = new char[strlen((const char*)arg->argumentValue)];
                strcpy((char*)out->_requiredClass, (const char*)arg->argumentValue);

            }
            else if ((arg = node->ConsumeArgument("linkMasterpiecePassivityCategoryId")))
            {
                out->_linkMasterpiecePassivityCategoryId = new char[strlen((const char*)arg->argumentValue)];
                strcpy((char*)out->_linkMasterpiecePassivityCategoryId, (const char*)arg->argumentValue);

            }
            else if ((arg = node->ConsumeArgument("linkPassivityCategoryId")))
            {
                out->_linkPassivityCategoryId = new char[strlen((const char*)arg->argumentValue)];
                strcpy((char*)out->_linkPassivityCategoryId, (const char*)arg->argumentValue);

            }
            else if ((arg = node->ConsumeArgument("linkPassivityId")))
            {
                out->_linkPassivityId = new char[strlen((const char*)arg->argumentValue)];
                strcpy((char*)out->_linkPassivityId, (const char*)arg->argumentValue);

            }
            else if ((arg = node->ConsumeArgument("linkCrestId")))
            {
                out->_linkCrestId = new char[strlen((const char*)arg->argumentValue)];
                strcpy((char*)out->_linkCrestId, (const char*)arg->argumentValue);
            }
            else if ((arg = node->ConsumeArgument("linkCustomizingId")))
            {
                out->_linkCustomizingId = new char[strlen((const char*)arg->argumentValue)];
                strcpy((char*)out->_linkCustomizingId, (const char*)arg->argumentValue);
            }
            else if ((arg = node->ConsumeArgument("linkEquipmentId")))
            {
                out->_linkEquipmentId = new char[strlen((const char*)arg->argumentValue)];
                strcpy((char*)out->_linkEquipmentId, (const char*)arg->argumentValue);
            }
            else if ((arg = node->ConsumeArgument("linkLookInfoId")))
            {
                out->_linkLookInfoId = new char[strlen((const char*)arg->argumentValue)];
                strcpy((char*)out->_linkLookInfoId, (const char*)arg->argumentValue);
            }
            else if ((arg = node->ConsumeArgument("linkPetAdultId")))
            {
                out->_linkPetAdultId = new char[strlen((const char*)arg->argumentValue)];
                strcpy((char*)out->_linkPetAdultId, (const char*)arg->argumentValue);
            }
            else if ((arg = node->ConsumeArgument("linkPetOrbId")))
            {
                out->_linkPetOrbId = new char[strlen((const char*)arg->argumentValue)];
                strcpy((char*)out->_linkPetOrbId, (const char*)arg->argumentValue);
            }
            else if ((arg = node->ConsumeArgument("linkSkillId")))
            {
                out->_linkSkillId = new char[strlen((const char*)arg->argumentValue)];
                strcpy((char*)out->_linkSkillId, (const char*)arg->argumentValue);
            }
            else if ((arg = node->ConsumeArgument("linkEnchantId")))
            {
                out->_linkEnchantId = new char[strlen((const char*)arg->argumentValue)];
                strcpy((char*)out->_linkEnchantId, (const char*)arg->argumentValue);

            }
            else if ((arg = node->ConsumeArgument("dropIdentify")))
            {
                out->_dropIdentify = ((const char*)arg->argumentValue) == "True" ? 1 : 0;
            }


        }
        out_items.push_back(out);
    }

}

The XMLDocumentParser::ParseXMLDocument goes well, but when i'm get IItems out of XMLNodes [as shown above] [with program compiled in Release mode VS2015] it crashes randomly at delete _arguments[i];

XMLDocumentParser::XMLNode::~XMLNode()
{
    if (tagName)
    {
        delete[] tagName;
        tagName = 0;
    }

    //clean arguments
    for (size_t i = 0; i < _arguments.size(); i++)
    {
        if (_arguments[i])
        {
            delete _arguments[i];
            _arguments[i] = 0;
        }
    }
    _arguments.clear();

    //clean childNodes
    for (size_t i = 0; i < childNodes.size(); i++)
    {
        if (childNodes[i])
        {
            delete childNodes[i];
            childNodes[i] = 0;
        }
    }
    childNodes.clear();

    parentNode = 0;
}

Why is that happening...Please help. Thanks!

Aucun commentaire:

Enregistrer un commentaire