Search code examples
cmallocfreedynamic-memory-allocationcalloc

free() loop, is triggering a break point and seems to not free the element


I have been working on an assignment which is pretty much done, and all I need to do is free the the double pointer allocated memory, but with the loop when I go through the loop it triggers a break point and seems to not clear it all I'm not sure whats triggering it. Context: the Create Data function is basically a function that returns a malloc.

int main(void){



int i;
    static STUDENT** records; 
    static float averageTotal[SIZE];
    createData(); 
    records = calloc(3, sizeof(STUDENT*));
    for (i = 0; i < 3; i++){
        records[i] = createData();
    }

    menu(records, userinput, &averageTotal[0]); 
    int c;
    for (c = 0; c < 3; c++){


            free(records[c]);


    }
    free(records);


    return 0;

}
STUDENT* createData()
{
    STUDENT* result;
    result = malloc(3*sizeof(STUDENT*));
    return result;
}

EDIT: added Menu for Context

void menu(STUDENT* records, int user_size, float* averageTotal[]){
    int menuV = 0;
    do{

        int userinput;  
        int i;
        static int counter = 0;
        printf("       **********************************\n");
        printf("       *        MENU                    *\n");
        printf("       *  1. Add Student                *\n");
        printf("       *  2. Display all student records*\n");
        printf("       *  3. Quit                       *\n");
        printf("       **********************************\n");
        scanf_s("%d%*[^\n]", &userinput); '\n' == getchar();
        switch (userinput){
            // switch statement with loops.
        case 1:do
        {
            addStudent(records, &counter, user_size);
            printf("Add another record? 1(y) 2(n)\n");
            scanf_s("%d%*[^\n]", &userinput); '\n' == getchar();
        } while (userinput == 1);
        break;
        case 2:
        do{
            displayStudent(records, user_size);
            printf("Display again? 1(y) 2(n)\n");
            scanf_s("%d%*[^\n]", &userinput); '\n' == getchar();
        } while (userinput == 1);
        break;

        case 3:
            menuV++;
                break;





        }
    } while (menuV == 0);
}

Edit: added addStudent Function for Context

void addStudent(STUDENT* records[], int* counter, int user_size)

{ // A simple function that lets the user add values to the struct. The counter keeps track and changes the element.
    printf("Student: %d", (*counter+1));
    printf(" of 3\n");
    printf("Enter name:\n");
    fgets(records[*counter]->name, 40, stdin);
    printf("Enter Exam 1 Score: \n");
    scanf_s("%f", &records[*counter]->exam1); 
    printf("Enter Exam 2 Score: \n");
    scanf_s("%f", &records[*counter]->exam2);
    printf("Name:%s",records[*counter]->name);
    printf("Exam 1:%0.2f\n", records[*counter]->exam1);
    printf("Exam 2:%0.2f\n", records[*counter]->exam2);
    (*counter)++;


}

Solution

  • There's lots of things wrong here. You seem to have a weak grasp of pointers and dereference.

    This line:

    static STUDENT** records;
    

    Creates a variable that's a pointer to a pointer to a datatype.

    Ideally you should change the declaration to something that's idiomatic and easier to understand without thinking. Something like:

    records = calloc(3, sizeof(*records));
    

    In the function CreateData() you're assigning the members of records to a pointer to 3 pointers.

    This line:

    result = malloc(3 * sizeof(*STUDENT));
    

    Should read:

    result = malloc(3 * sizeof(STUDENT));
    

    . The seconds allocates memory for three times the length of the datatype STUDENT. (What you want).

    Moving on --

    Here is the declaration/definition of the function menu.

    void menu(STUDENT* records, int user_size, float* averageTotal[])
    

    And here's how you've used it in your code:

    menu(records, userinput, &averageTotal[0]);
    

    the first parameter, records, was defined as a pointer-to-pointer-to-STUDENT. But the definition of menu expects only a pointer-to-STUDENT.

    Looking at the rest of the code, it's the definition that's incorrect and not the function call.

    Same function:

    void menu(STUDENT* records, int user_size, float* averageTotal[])
    

    menu expects a pointer-to-pointer-to-float for its third parameter. But you provided a pointer-to-index in the call here:

    menu(records, userinput, &averageTotal[0]);
    

    Without reading much further, it's clear you need to understand pointers better(or stop typing so fast and understand what you're writing!).

    Finally, an actual nit-pick. The function CreateData() should be removed and its use should be replaced by function calls to calloc/malloc() directly.