Я пытаюсь создать интерпретатор 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>}
Надеюсь, этого достаточно, чтобы понять мою проблему, заранее спасибо за вашу помощь.