为什么这个解释器会导致分段错误?

问题描述 投票:0回答:1

我正在尝试用 C 编写一个 brainf*ck Interpreter。 当前指针、数组和数组的长度在结构中给出。

解释器方法接收指向数组结构的指针和 brainf*ck 指令作为字符串。如果指令有效,该方法可能返回 1,否则返回 0。

我不明白这个错误可能发生在哪里。也许是一个错误的指针。

struct Array {
  size_t array_len;
  uint8_t* array;

  uint8_t* cur;
};

int brainfuckInterpreter(struct Array* state, const char* program) {
  
  uint8_t ptr = *(state->cur);    // loading the the pointer for the array
  char prog_curr;
  uint8_t brk_count;                // bracket-counter for jump commands
  uint8_t i = 0;                  // counter for the array
  while( i < state->array_len-1){
     
    if(ptr > state->array_len || ptr < 0){        // check if the array-pointer is within the array
      return 0;
    }

      prog_curr = *(program+i++);                   // Loading the next command of the string program

      switch (prog_curr){
      case '.': putchar( state->array[ptr]); break;
      case '+': {state->array[ptr]++;} break;
      case '-': {state->array[ptr]--;} break;
      case '>': {
          if(ptr >= state->array_len){
            return 0;
          }else {
            ptr++;
          }
      } break;
      case '<': {
          if(ptr < 0){
            return 0;
          }else {
        ptr--;
      } break;
      }
      case '[': {
          if( state->array[ptr] == 0 ){
            brk_count = 0;
            prog_curr = *(program + ptr);
            do{
              if(prog_curr == '['){brk_count++;};
              if(prog_curr == ']'){brk_count--;};
              if(brk_count != 0){
                ptr++;
                prog_curr = *(program+ptr);
              }
            } while (brk_count != 0);
        }else{
          ptr++;
        }
      } break;
      case ']': {
        if(state->array[ptr] == 0){
          brk_count = 0;
          prog_curr = *(program + ptr);
          do{
            if(prog_curr == '['){brk_count--;};
            if(prog_curr == ']'){brk_count++;};
            if( brk_count != 0){
              ptr--;
              prog_curr = *(program + ptr);
            }  
          } while (brk_count != 0);
            
        }else{
          ptr++;
        }
      } break;
      default: {ptr++;} break;   // all other characters are getting ignored
    } 
  }
  return 1;
}
c pointers segmentation-fault interpreter brainfuck
1个回答
0
投票

几个问题。

你把 ptr 和 i 搞混了;您开始使用 ptr 作为数组中的位置,而 i 作为程序中的位置,但是您将 i 与 state->array_len 而不是程序的长度进行比较,然后在以后的括号处理代码中使用“ptr”对于两个变量。

(此外,您的括号代码假定程序索引仍指向当前命令,但您在循环开始时自动递增 i。)

(并且非命令的默认操作不应该增加 ptr 或 i 因为你非常合理地不把它留给单独的命令来做,所以明确地这样做会使它发生两次。与“其他”情况相同括号处理,至少如果您更改为在最外层 while 循环的末尾递增 i 或使其成为 for 循环。)

另外:通过将 ptr 和 i 以及 *cur 定义为字节,您可以将 brainfuck 数组和程序的长度限制为 256 字节,这是不行的。副手我建议 16 兆字节作为一个很好的限制。

你的']'代码中的测试也颠倒了(应该跳回 NONzero),并且你有一个 off-by-one 检查“ptr > state->array_len”而不是“ptr >= state->array_len “.

© www.soinside.com 2019 - 2024. All rights reserved.