Структура указатель странное поведение - PullRequest
0 голосов
/ 16 февраля 2019

Я пытаюсь создать интерпретатор BrainFuck (BF), используя двусторонний связанный список.Однако то, как я двигаюсь по этому списку, кажется довольно странным образом влияет на клетки.

Итак, сначала вот часть моей программы, которая доставляет мне неприятности

int main(int argc, char **argv)
{
    Cell c = {NULL, NULL, '\0', NULL};
    Cell* codeCell = &c;
    Cell b = {NULL, NULL, '\0', NULL};
    Cell* bandCell = &b;

    //init
    bandCell->val = '\0';
    bandCell->firstCell = bandCell;

    codeCell->firstCell = codeCell;

    //get code
    printf("BF code : ");
    codeCell->val=getchar();
    while(codeCell->val != '\n') {
        if(
            codeCell->val=='<'||codeCell->val=='>'
            ||codeCell->val=='+'||codeCell->val=='-'
            ||codeCell->val=='['||codeCell->val==']'
            ||codeCell->val==','||codeCell->val=='.'
        ) {
            newCell(codeCell)->val = getchar();
            codeCell = codeCell->nextCell;
        }
        else {
            codeCell->val = getchar();
        }
    }
}

Структура Cell определяется следующим образом:

typedef struct Cell Cell;
struct Cell {
    Cell* precCell;
    Cell* nextCell;
    char val;
    Cell* firstCell;
};

И функция Cell* newCell(Cell*) выглядит следующим образом:

Cell* newCell (Cell* precCell) {
    Cell n = {precCell, NULL, '\0', precCell->firstCell};
    Cell* newCell = &n;
    precCell->nextCell = newCell;
    return newCell;
}

В этом я пытаюсь получить пользовательский ввод char с помощью char и поместить его вячейка, только если это правильная инструкция BF.В итоге у меня был SEGFAULT, поэтому я попытался найти его источник, и я думаю, что это происходит из-за этого странного поведения в строке 42: когда я пытаюсь обновить val недавно созданной ячейки с тем, что находится в getchar() буфер, ячейка codeCell->nextCell теряет все свои значения, но я уверен, что это та же самая ячейка, потому что адрес все тот же.В следующем примере GDB вы можете увидеть тест того, что я только что сказал.

BF code : .

Breakpoint 1, main (argc=1, argv=0x742278) at bf_debug_test.c:42
42                              newCell(codeCell)->val = getchar();
(gdb) s
newCell (precCell=0x28ff18) at bf_debug_test.c:13
13              Cell n = {precCell, NULL, '\0', precCell->firstCell};
(gdb)
14              Cell* newCell = &n;
(gdb)
15              precCell->nextCell = newCell;
(gdb)
16              return newCell;
(gdb) p precCell
$1 = (Cell *) 0x28ff18
(gdb) p *precCell
$2 = {precCell = 0x0, nextCell = 0x28fed4, val = 46 '.', firstCell = 0x28ff18}
(gdb) p newCell
$3 = (Cell *) 0x28fed4
(gdb) p *newCell
$4 = {precCell = 0x28ff18, nextCell = 0x0, val = 0 '\000',
  firstCell = 0x28ff18}
(gdb) s
17      }
(gdb)
main (argc=1, argv=0x742278) at bf_debug_test.c:43
43                              codeCell = codeCell->nextCell;
(gdb) p codeCell
$5 = (Cell *) 0x28ff18
(gdb) p *codeCell
$6 = {precCell = 0x0, nextCell = 0x28fed4, val = 46 '.', firstCell = 0x28ff18}
(gdb) p codeCell->nextCell
$7 = (Cell *) 0x28fed4
(gdb) p *codeCell->nextCell
$8 = {precCell = 0x76ad7220 <msvcrt!_local_unwind4+464>,
  nextCell = 0x1d6aff2c, val = 10 '\n',
  firstCell = 0x76acf24c <msvcrt!getc+188>}

Надеюсь, этого достаточно, чтобы понять мою проблему, заранее спасибо за вашу помощь.

...