尝试使用用户输入时的AddressSanitizer:DEADLYSIGNAL

时间:2018-10-20 17:25:11

标签: c

这是我拥有的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdbool.h>
#include <assert.h>
#include <time.h>

const int Win = 0, Lose = 1, Draw = 2;
const int Rock = 0, Paper = 1, Scissors = 2;

int input(int n, char i[n]){
  if (i[0] == 'R' || i[0] == 'r') return Rock;
  else if (i[0] == 'P' || i[0] == 'p') return Paper;
  else if (i[0] == 'S' || i[0] == 's') return Scissors;
  else return -1;
}

int game(int n){
  srand(time(NULL));
  int r = rand() % 2;
  if (r == n) return Draw;
  else if (r == 0 && n == 1) return Win;
  else if (r == 0 && n == 2) return Lose;
  else if (r == 1 && n == 0) return Lose;
  else if (r == 1 && n == 2) return Win;
  else if (r == 2 && n == 0) return Win;
  else if (r == 2 && n == 1) return Lose;
  else return 0;
}

void print(int game){
  if (game == Draw && input == Rock) printf ("i chose rock, its a draw\n");
  else if (game == Draw && input == Paper) printf ("i chose paper, its a draw\n");
  else if (game == Draw && input == Scissors) printf ("i chose scissors, its a draw\n");
  else if (game == Win && input == Rock) printf ("i chose scissors, you win\n");
  else if (game == Win && input == Paper) printf ("i chose rock, you win\n");
  else if (game == Win && input == Scissors) printf ("i chose paper, you win\n");
  else if (game == Lose && input == Rock) printf ("i chose paper, you lose\n");
  else if (game == Lose && input == Paper) printf ("i chose scissors, you lose\n");
  else printf ("i chose rock, you lose\n");
}

// void checkInput(){
//     assert(input(1, 'R') == 1);
//     assert(input(1, 'r') == 1);
//     assert(input(1, 'P') == 2);
//     assert(input(1, 'p') == 2);
//     assert(input(1, 'S') == 3);
//     assert(input(1, 's') == 3);
//     printf("all tests pass\n");
// }

int main(){
  setbuf(stdout, NULL);
  char *j[1];
  for(int a = 0; a >= 0; a++){
    printf("pick rock, paper, scissors (R/P/S) 'e' to exit\n");
    scanf("%s", &*j[0]);
    if (j[0] == 'e') break;
    print(game(input(strlen(j[0]), j[0])));
  }
  return 0;
}

当我运行它时,它会打印出一行并让我输入一些内容,然后它会给我这个错误

pick rock, paper, scissors (R/P/S) 'e' to exit
R
AddressSanitizer:DEADLYSIGNAL
=================================================================
==4029==ERROR: AddressSanitizer: SEGV on unknown address 0x7f5ca33d6787 (pc 0x7f5ca328ffdd bp 0x7ffca0431550 sp 0x7ffca0430e70 T0)
==4029==The signal is caused by a WRITE memory access.
    #0 0x7f5ca328ffdc  (/lib/x86_64-linux-gnu/libc.so.6+0x6cfdc)
    #1 0x7f5ca329f12b  (/lib/x86_64-linux-gnu/libc.so.6+0x7c12b)
    #2 0x4a724c  (/home/student/Documents/extra+0x4a724c)
    #3 0x4a734e  (/home/student/Documents/extra+0x4a734e)
    #4 0x512a5e  (/home/student/Documents/extra+0x512a5e)
    #5 0x7f5ca3244b96  (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
    #6 0x419e19  (/home/student/Documents/extra+0x419e19)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (/lib/x86_64-linux-gnu/libc.so.6+0x6cfdc) 
==4029==ABORTING

我怎样才能阻止这种情况的发生,因为此错误对我而言毫无意义,并且看不到任何可能有问题的信息。我知道我粘贴了很多代码,但是我认为您需要查看所有代码才能知道它从哪里崩溃的。

1 个答案:

答案 0 :(得分:1)

您需要打开编译器警告:您的代码中存在一些重大问题。

表格的行:

else if (game == Draw && input == Paper) printf ("i chose paper, its a draw\n");

将输入(它是一个函数指针)与一个整数进行比较。如果允许,编译器会警告您有关此问题的信息。这样做,然后重试,并在需要时寻求帮助。

此外,您没有正确使用scanf。查找有关scanf的堆栈溢出问题,并打印从scanf返回的值以调试程序。

祝您好运,遇到困难时不要犹豫,问另一个问题。