访问Struct Array时抛出异常

时间:2018-05-15 04:19:10

标签: c pointers struct

当我调用test()函数时,它会提示我输入我的struct数组中第一个玩家的赌注。它接受我的条目。在我的for循环的第二轮中,当我在struct数组中请求第二个人的赌注时,在输入一个值后抛出异常:

  Exception thrown at 0x00577F81 (ucrtbased.dll) in lottery.exe: 
  0xC0000005: Access violation writing location 0x7B7CC9FC.

  If there is a handler for this exception, the program may be safely continued. 

这是我的代码:

void initNames(struct player *p, int size) {
  int i;
  for (i = 0; i < size; i++) {
      printf("Enter player %d's name...\n", (i + 1));
      scanf("%s", p[i].name);
  }
  return;
}

void initScore(struct player *p, int size) {
   int i;
   for (i = 0; i < size; i++) {
      p[i].wins = 0;
      p[i].losses = 0;
      p[i].funds = 100.00;
   }
   return;
}

void test(struct player *p, int size) {
  int i;
  for (i = 0; i < size; i++) {
    printf("%s, you have $%.2lf. Place your bet!\n", p[i].name, p[i].funds);
    scanf("%lf", p[i].bet);
  }
}

void main() {

  int size;
  struct player *playerPtr;

  printf("How many players?");
  scanf("%d", &size);
  playerPtr = malloc(sizeof(struct player)*size);

  initScore(&playerPtr, size);

  initNames(&playerPtr, size);

  test(&playerPtr, size);

  free(playerPtr);
}

感谢您提供任何帮助或解释!

1 个答案:

答案 0 :(得分:3)

宣布函数initNames的方式与您在main中调用函数的方式之间存在差异。

声明为 -

void initNames(struct player *p, int size);

这意味着它期望指向struct player的指针作为第一个参数,而int作为第二个参数。

主要是你称之为 -

struct player *playerPtr;
initNames(&playerPtr, size);

现在playerPtr的类型为struct player*,因此&playerPtr的类型为struct player**。因此,参数的类型不匹配。您的编译器应该已经警告过您。始终使用-Wall进行编译以查看所有警告,并-Werror将警告视为错误。

来修复 -

您不会在任何功能中修改playerPtr。所以你不需要通过struct player**。因此将调用更改为 -

initNames(playerPtr, size);

函数内部无需更改,因为函数的原型尚未更改。

完全相同的问题也与函数initScoretest有关。您可以通过将第一个参数更改为其调用来以类似的方式修复它们。

现在解决了这个问题后,该计划也没有问题。 看看这一行 -

scanf("%lf", p[i].bet);

我假设bet声明为double类型。您现在将double传递给scanf,其中double*是预期的。你需要传递赌注的地址。因此,将行更改为 -

scanf("%lf", &p[i].bet);

我修复了所有错误,工作版本是 Ideone

我假设了struct player的定义。

为了更加确定正在阅读的值,您应该始终将scanf的返回值检查为 -

int ret = scanf("%lf", p[i].bet);

if(ret == 0) {
    // Print appropriate error message that the value entered in not a double and ask the user to retry
} else if (ret == EOF) {
    // The input stream has been closed by the user without providing appropriate input, print appropriate error message and abort. 
}
// If execution reaches this point, p[i].bet is safe to use.