【发布时间】:2018-05-15 04:19:10
【问题描述】:
当我调用 test() 函数时,它会提示我为结构数组中的第一个玩家输入赌注。它接受我的输入。在我的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);
}
感谢您的帮助或解释!
【问题讨论】:
-
initScore(&playerPtr, size); --> initScore(playerPtr, size);和initNames和test类似 -
p[i].bet是正确的语法。因为p是struct player *,p[i]是struct player,你可以使用.bet。 -
写下来@AjayBrahmakshatriya - 你发现了主要问题。由于
playerPtr的地址在你的函数中没有改变——没有必要将它的地址传递给函数。只需传递指针。该函数将使用指针的副本,但该副本将指向(保存)与原始地址相同的地址——因此函数内的任何修改都将反映在调用者中(main()此处) -
现在如果
playerPtr没有在main()中分配,并且您希望将指针传递给函数进行分配,那么您需要将&playerPtr作为player **传递,这样您就可以将来自malloc的返回分配给相同的指针,例如*playerPtr = malloc (...)以便分配在main()中可见。在这种情况下,如果你只是传递一个指针,你将malloc返回的地址分配给原始的副本,并且副本的生命周期只延伸到函数的生命周期——导致内存泄漏并且没有分配指针在main(). -
如果您删除了
&,那么在您的函数中分配给数组的值应该没有问题(这很幸运,您选择了格式说明符 -- 忽略前导空格是出于巧合而非设计,但在 匹配 失败时将导致无限循环)唯一挥之不去的问题是您在下注时使用p[i].bet而不是&p[i].bet. 总是,总是检查scanf的return,每次必须处理3个案例:(1)EOF; (2) 匹配或输入失败;最后 (3) 次成功转换。