我编写了一个Secret Santa程序,该程序将读取许多游戏参与者,通过随机排列将每个参与者分配给其他参与者中的一个,确保没有参与者被分配给自己,然后给每个电子邮件发送电子邮件。
它似乎可以正确执行并提供预期的输出,但在执行结束前返回free(): invalid pointer
,然后中止。我在derange()
函数中似乎找不到的地方写信了吗?另外,我的随机排列逻辑看起来不错吗?它似乎测试得很好,但是我怀疑它没有给出真正的随机分布。
意识到memcpy()
甚至是shuffle()
之类的功能可以使我的生活更轻松,但这对我来说主要是一项学习练习-尽管我确实希望在学习期间利用它假期。友善,我才刚刚开始!
编辑:清理代码以获取更简单的示例。
struct person {
char name[30];
char emailAddress[30];
char secretSanta[30];
};
int main(void) {
int n;
scanf("%d", &n);
struct person * members = (struct person *) malloc(n * sizeof(struct person));
derange(members, n);
free(members);
return 0;
}
void derange(struct person * p, int n) {
srand(time(NULL));
int guesses[n];
int i, j, r;
for(i = 0; i < n; i++) {
r = (rand() % n);
if(r == i) {
i = -1;
// picked its own number, restart loop
} else {
for(j = 0; j < n; j++) {
if(r == guesses[j]) {
i = -1;
guesses[j] = -1;
// number already used, restart main loop
}
}
guesses[i] = r;
for(j = 0; j < 30; j++) {
p[i].secretSanta[j] = p[r].name[j];
}
}
}
}
答案 0 :(得分:2)
将guesses[i]
设置为-1后,您可能最终访问了p[i]
和i
:
添加一行:
} else {
for(j = 0; j < n; j++) {
if(r == guesses[j]) {
i = -1;
guesses[j] = -1;
// number already used, restart main loop
}
}
if (i == -1) continue; //Prevent accessing guesses[-1]
guesses[i] = r;
for(j = 0; j < 30; j++) {
p[i].secretSanta[j] = p[r].name[j];
}
}