jeudi 13 décembre 2018

Random derangement memory leak

I wrote a Secret Santa program that will read a number of game participants, assign each participant to one of the other participants by random derangement, making sure no participant is assigned to themselves, and send each an email.

It seems to execute properly and give intended output, but returns free(): invalid pointer at end of execution before aborting. Am I writing out of bounds somewhere in the derange() function that I can't seem to find? Additionally, does my random derangement logic look sound? It seems to test well, but I have a suspicion it does not give a truly random distribution.

Aware there are functions that could make my life easier like memcpy(), or even shuffle(), but this is mainly a learning exercise for me -- though I do hope to make use of it during the holidays. Be kind, I'm just getting started!

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

struct person {
    char name[30];
    char emailAddress[30];
    char secretSanta[30];
};

void readPerson(struct person *, int);
void derange(struct person *, int);

int main(void) {
    int n;
    printf("Enter number of players: ");
    scanf("%d", &n);
    struct person * members = (struct person *) malloc(n * sizeof(struct person));

    for(i = 0; i < n; i++) {
        readPerson(&members[i], i);
    }

    derange(members, n);

    // (send emails to members)

    free(members);
    return 0;
}

void readPerson(struct person * p, int n) {
    printf("Player %d\n", n+1);
    printf("  Enter player name: ");
    scanf("%s", p->name);
    printf("  Enter Player email address: ");
    scanf("%s", p->emailAddress);
}

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];
            }
        }
    }
}




Aucun commentaire:

Enregistrer un commentaire