Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

crash when in release mode when writing to a global array defined main.cpp



  • Hi,

    I am having a strange issue with a C++/QT programming I am writing

    In my program I have two UIs one for the main window and one for a dialog that is popped up when a action is selected from a menu off a qtreeview. The dialog is supposed to be used to add more things to the tree.

    I have a global class that holds a large char array. This is supposed to hold all the data I want to save. I am using a malloc to allocate the data. I have no trouble writing to this array when in my mainwindow class. However when I try to write to the array when in the dialog class and I am in release the program sometimes (about 30 % of the time) dies. It works perfectly in debug mode and the array data in debug mode looks correct. All the pointers look to be pointing to the correct spots in memory when in debug mode.

    Does anyone have any idea what might be going wrong.

    The main.cpp

    GameMemoryMan GmemMan;
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        GMemMan.setBaseMemorySize((int64_t)1000000000);
        MainWindow w;
        w.init();
        w.show();
        return a.exec();
    }
    

    In the .h for the GameMemoryMan

    #define TO_PTR(Type, Index, MeM) Index == 0 ? nullptr : (Type*)(&MeM.GameData[Index])
    #define TO_INDEX(PTR, MeM)  PTR == nullptr ? 0 : ((unsigned char*) PTR - (MeM.GameData));
    #define GET_PTR(Type, MeM) (Type*)(&MeM.WritePoint[0]);MeM.WritePoint = MeM.WritePoint + sizeof(Type);
    #define GET_TYPE(PTR) (*(int64_t*)(PTR))
    class GameMemoryMan
    {
    public:
        GameMemoryMan(){}
        ~GameMemoryMan(){}
        int setBaseMemorySize(int64_t );
        int LoadGameMemory(std::string GameLoction);
        int SaveGameLocation(std::string GameLocation);
        int64_t WriteMem(void*, int64_t );
        int64_t GetIndex(void* pointer);
        std::string ReadString(int64_t index);
        int64_t WriteString(std::string TheString);
        void CheckMemorySize();//check if more data is needed. Must be done regulerly;
    
        unsigned char *GameData;
        unsigned char *WritePoint= nullptr;
        int64_t BaseMemSize = 0;
    private:
    };
    
    //DataBlock: 002
    struct location_node
    {
        int64_t Type = 2;
        int64_t name_inx; //string
        int64_t Parent_inx; //002 or 001 if Top
        int64_t child_inx; // 002 or 003
        int64_t siblings_inx; // 002 or 003
        int64_t packing[16];
    };
    extern GameMemoryMan GMemMan;
    

    In the cpp for the GameMemoryMan

    int GameMemoryMan::setBaseMemorySize(int64_t Size)
    {
        GameData = (unsigned char*) malloc(Size*sizeof(unsigned char));
        BaseMemSize = Size;
        memset(GameData, 0, Size);
        //((MainGame*)(GameData))->BaseMemSize = BaseMemSize;
        //MainGame* pointer = TO_PTR(MainGame, 0, this);//(MainGame*)(&GameData[0]);
        MainGame* pointer = (MainGame*)(&this->GameData[0]);
        pointer->BaseMemSize = BaseMemSize;
        //int64_t* pointer = (int64_t*)(&GameData[0]);
        //pointer = BaseMemSize;
        return 0;
    }
    

    //This creates the Dialog

    void MainWindow::AddLocation()
    {
         AddNewLocation NewLocationDialog;
         NewLocationDialog.setModal(true);
         NewLocationDialog.exec();
        return;
    }
    

    Dies when this is run

    void AddNewLocation::AddLocation()
    {
        std::string nameOfLocation = ui->lineEdit->text().toStdString();
        if(treemodel->findItems(nameOfLocation.c_str(), Qt::MatchContains | Qt::MatchRecursive, 0).isEmpty())
        {
    
            RoomNode* item0 = new RoomNode(folder, nameOfLocation.c_str());
            location_node* newlocation = GET_PTR(location_node, GMemMan);
            item0->savedata = newlocation;
            newlocation->Type = 2; //code sometimes dies hear
            newlocation->name_inx = GmemMan.WriteString(nameOfLocation); // or hear
            treeNodeParent->appendRow(item0);
    
        return;
    }
    

  • Qt Champions 2019

    @skalloz said in crash when in release mode when writing to a global array defined main.cpp:

    location_node* newlocation = GET_PTR(location_node, GMemMan);
    item0->savedata = newlocation;
    newlocation->Type = 2; //code sometimes dies hear
    newlocation->name_inx = GmemMan.WriteString(nameOfLocation); // or hear

    Your code is not really clear: how does your MainWindow access GmemMan which was defined in main.cpp?
    What is GET_PTR? You do not check the pointer it returns before dereferencing it.
    You are allocating 8GB memory chunk if I'm not mistaken. Such an allocation can fail if there is no chunk of that size available.

    "Dies when this is run" - dies in what way? SIGSEGV? Something else?


Log in to reply