0

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;
}
  • `GameData = (unsigned char*) malloc(Size*sizeof(unsigned char));` - don't use `malloc` in C++. Just don't. And a C-style cast on top? – Jesper Juhl May 28 '20 at 20:55
  • Also, even if you were to use `malloc`, you did not check if it returned NULL. Also `std::vector GameData;` then `GameData.resize(Size);` is more what C++ should look like rather than using `malloc`. – PaulMcKenzie May 28 '20 at 20:59
  • Paul thanks but I need contiguous memory and i don't think a vector is contiguous. – sageann kalloz May 28 '20 at 21:59
  • Jesper thanks. What do you think i should use. The normal array type declaration can't make a large enough array – sageann kalloz May 28 '20 at 22:00
  • 2
    @sageannkalloz, a vector is _very_ contiguous: https://stackoverflow.com/questions/849168/are-stdvector-elements-guaranteed-to-be-contiguous – JKSH May 28 '20 at 22:20
  • Also if you do malloc(Size*sizeof(unsigned char));, you should do memset(GameData, 0, Size*sizeof(unsigned char)); If Size and Size*sizeof(unsigned char) differs you could get garbage in release build in GameData. But actually they should be the same size because sieof(unsigned char) is mostly 1. Anyway like Paul says if you do C++ try to do all the things in C++ and not mix it up with pure C functions. Qt has great tools for such things, for example QSharedMemory, vectors, etc... – Xplatforms May 29 '20 at 07:13
  • @sageannkalloz A vector stores its data in contiguous memory. It is guaranteed to do so. You access the buffer allocated by either calling the `data()` member function, or just as your code is doing now `&this->GameData[0]`. – PaulMcKenzie May 29 '20 at 09:42

0 Answers0