cra sh в режиме выпуска при записи в глобальный массив, определенный в main. cpp из диалогового окна - PullRequest
0 голосов
/ 28 мая 2020

У меня странная проблема с программированием на C ++ / QT Я пишу

В моей программе у меня есть два пользовательских интерфейса: один для главного окна и один для диалогового окна, которое появляется при выборе действия из меню qtreeview. Предполагается, что диалоговое окно будет использоваться для добавления дополнительных элементов в дерево.

У меня есть глобальный класс, содержащий большой массив символов. Он должен содержать все данные, которые я хочу сохранить. Я использую mallo c для размещения данных. У меня нет проблем с записью в этот массив в моем классе mainwindow. Однако, когда я пытаюсь записать в массив, когда я нахожусь в классе диалога, и я нахожусь в выпуске, программа иногда (примерно в 30% случаев) умирает. Он отлично работает в режиме отладки, и данные массива в режиме отладки выглядят правильно. Все указатели в режиме отладки выглядят так, будто указывают на правильные места в памяти.

Кто-нибудь знает, что может пойти не так.

Основной. 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();
}

В .h для 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;

В cpp для 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;
}

// Это создает диалог

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

Умирает при запуске

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;
}
...