Отменить и повторить структурные массивы в C - PullRequest
0 голосов
/ 17 марта 2020

Привет, поэтому я пытаюсь реализовать функцию отмены-повтора в своем назначении Uni. Я должен сделать реализацию «сохранить массив», но она не работает правильно. Моя структура репозитория имеет поле, в котором хранится индекс последнего элемента, поэтому после добавления чего-либо оно будет равно 0. Ну, после того, как оно пройдет через отмену, оно станет большим отрицательным числом. Это мой исходный код: '' '

#include"UndoRedo.h"
#include<stdlib.h>

Undo* createUndo(Repo* repo) {
    Undo* undo = (Undo*)malloc(sizeof(Undo));
    undo->undo = (Repo*)malloc(sizeof(Repo) * 10);
    undo->availableUndos = 0;
    undo->undoSlots = 10;
    return undo;
}
Redo* createRedo(Repo* repo) {
    Redo* redo = (Redo*)malloc(sizeof(Redo));
    redo->redo = (Repo*)malloc(sizeof(Repo) * 10);
    redo->availableRedos = 0;
    redo->redoSlots = 10;
    return redo;
}
void addUndo(Repo* repo, Undo* undo) {
    if (undo->undoSlots < undo->availableUndos + 1) {
        growUndo(undo);
        undo->availableUndos += 1;
        undo->undo[undo->availableUndos] = *repo;
    }
}
void destroyUndoAndRedo(Redo* redo, Undo* undo) {
    free(undo->undo);
    free(undo);
    free(redo->redo);
    free(redo);
}
void addRedo(Undo* undo, Redo* redo) {
    if (redo->redoSlots < redo->availableRedos + 1) {
        growRedo(redo);
        redo->availableRedos += 1;

    }
}
int undo(Redo* redo, Repo* repo, Undo* undo) {
    addRedo(undo, redo);
    //printf("%d", repo->indexOfTheLastItem);
    *repo = undo->undo[undo->availableUndos];
    //printf("%d", repo->indexOfTheLastItem);
    undo->availableUndos--;

}
int redo(Repo* repo, Redo* redo, Undo* undo) {
    addUndo(repo, undo);
    *repo = redo->redo[redo->availableRedos-1];
    redo->availableRedos--;

}
void growRedo(Redo* redo) {
    redo->redoSlots *= 2;
    redo->redo = realloc(redo->redo, sizeof(Repo) * redo->redoSlots);
}
void growUndo(Undo* undo) {
    undo->undoSlots *= 2;
    undo->undo = realloc(undo->undo, sizeof(Repo) * undo->undoSlots);
}

' ''

А вот как создаются отмены и повторы: '' '

#include"Repo.h"
typedef struct {
    Repo* undo;
    int undoSlots;
    int availableUndos;
}Undo;

typedef struct {
    Repo* redo;
    int redoSlots;
    int availableRedos;
}Redo;

'' '

Также репо выглядит так:' ''

typedef struct {
    Item* items;
    int allocatedSlots;
    int indexOfTheLastItem;
}Repo;

Repo* initRepo() {

    Repo* repo = (Repo *)malloc(sizeof(Repo));
    repo->items = (Item *)malloc(sizeof(Item) * 5);// Init the items array with 5 slots
    repo->allocatedSlots = 5;
    repo->indexOfTheLastItem = -1;
    return repo;
}

'' 'Я проверил, и они распределяются очень хорошо. Я просто не знаю, что происходит, потому что после того, как Репо проходит через отмену, я не могу получить доступ к его значениям (нарушение прав чтения). Спасибо за любые усилия!

1 Ответ

2 голосов
/ 17 марта 2020

В addUndo, если есть уже место для следующего элемента, вы не сохраняете его [вы сохраняете только тогда, когда растете это] .

И вы храните один за пределами того, что вам нужно (то есть вы должны увеличить доступный счетчик после , который вы храните).

Возможно, вы захотите:

void
addUndo(Repo *repo, Undo *undo)
{

    if (undo->undoSlots < undo->availableUndos + 1)
        growUndo(undo);

    undo->undo[undo->availableUndos] = *repo;

    undo->availableUndos += 1;
}

Аналогично для addRedo ...

...