我有一个数据库应用程序,添加和删除了一些记录后,我进入情况6以释放内存并退出应用程序。我知道我退出程序存储器后会自动获得免费,但正如老师所说,我会这样做。删除记录时遇到的堆损坏同样问题,然后尝试释放最后一条记录。在下面可以找到我的程序。我知道要更长一些,但经过很多天又几个小时,我无法确定问题所在。在下面,您将找到我的代码。

    #include <stdio.h>
    #include <malloc.h>
    #include <string.h>

    typedef struct StudentDynamic
    {
        char* firstName;
        char* lastName;
        float grade;
    }StudentDynamic;

    void exportCSV(char *filename, StudentDynamic* pStudents, int nStudents)
    {
    printf("\n Creating %s.csv file. \n ", filename);
    FILE *fp;
    filename = strcat(filename, ".csv");
    fp = fopen(filename, "wb+");
    fprintf(fp, "Student No., First Name, Last Name, Grade");
    for (int i = 0; i<nStudents; ++i)
    {
    fprintf(fp, "\n%d", i + 1);
    fprintf(fp, ",%s ", pStudents[i].firstName);
    fprintf(fp, ",%s ", pStudents[i].lastName);
    fprintf(fp, ",%f ", pStudents[i].grade);
    }
    fclose(fp);
    printf("\n File %s succesfully created!\n", filename);
    }

    void printStudents(StudentDynamic* pStudents, int nStudents)
    {
    printf("==========");
    printf(" List of Students");
    printf(" ========== \n");
    for (int i = 0; i < nStudents; ++i)
    {
    printf("%d. %12s %12s %8.2f", i + 1,
        pStudents[i].firstName,
        pStudents[i].lastName,
        pStudents[i].grade);
    printf("\n");
    }
    }


    void rewriteFile(StudentDynamic* pStudents, int nStudents)
    {
    for (int i = 0; i < nStudents - 1; ++i)
    for (int j = i + 1; j < nStudents; ++j)
    {
        if (pStudents[i].grade > pStudents[j].grade)
        {
            StudentDynamic aux;
            aux = pStudents[i];
            pStudents[i] = pStudents[j];
            pStudents[j] = aux;
        }
    }

    FILE *rwF;
    rwF = fopen("logfile.bin", "wb");

    for (int i = 0; i<nStudents; ++i)
    {
    fprintf(rwF, "%s\n", pStudents[i].firstName);
    fprintf(rwF, "%s\n", pStudents[i].lastName);
    if (i + 1 == nStudents)
    {
        fprintf(rwF, "%f", pStudents[i].grade);
        break;
    }
    fprintf(rwF, "%f\n", pStudents[i].grade);
    }
    fclose(rwF);
    }


    int main()
    {
    int nStudents, i = 0;
    StudentDynamic* pStudents = NULL;
    char auxfirstName[255], auxlastName[255];
    float auxGrade, updGrade;
    FILE *pFile;
    pFile = fopen("logfile.bin", "rb");
    if (pFile == NULL)
    {
    printf("Could not open file or is empty! Exiting...");
    exit(2);
    }
    while (!feof(pFile) && pFile != " ")
    {
    pStudents = (StudentDynamic*)realloc(pStudents, sizeof(StudentDynamic)*(i + 2));
    fscanf(pFile, "%s", auxfirstName);
    pStudents[i].firstName = (char*)malloc(strlen(auxfirstName) + 1);
    strcpy(pStudents[i].firstName, auxfirstName);

    fscanf(pFile, "%s", auxlastName);
    pStudents[i].lastName = (char*)malloc(strlen(auxlastName) + 1);
    strcpy(pStudents[i].lastName, auxlastName);

    fscanf(pFile, "%f", &auxGrade);
    pStudents[i].grade = auxGrade;

    strcpy(auxfirstName, "");
    strcpy(auxlastName, "");
    auxGrade = 0;
    i++;
    }
    nStudents = i;

    for (int i = 0; i < nStudents - 1; ++i)
    for (int j = i + 1; j < nStudents; ++j)
    {
        if (pStudents[i].grade > pStudents[j].grade)
        {
            StudentDynamic aux;
            aux = pStudents[i];
            pStudents[i] = pStudents[j];
            pStudents[j] = aux;
        }
    }
    fclose(pFile);

    char choice;
    printf("\t\t================== STUDENT DATABASE APPLICATION ==================");
    printf("\n\n");
    printf(" \n\t\t\t============================================");
    printf("\n \t\t\t  1. Create Student");
    printf("\n \t\t\t  2. Update Record");
    printf("\n \t\t\t  3. Delete Record");
    printf("\n \t\t\t  4. Export DB to CSV");
    printf("\n \t\t\t  5. List Students");
    printf("\n \t\t\t  6. Exit Program");
    printf(" \n\t\t\t============================================");
    printf("\n\n");
    printf("  Select Your Choice : ");
    getch();
    while (1)
    {
    choice = getchar();
    switch (choice)
    {
    case '1':
        nStudents++;
        pStudents = (StudentDynamic*)realloc(pStudents, sizeof(StudentDynamic) * (nStudents + 1));
        printf("Details of the new student:\n");
        printf("First name: ");
        scanf("%s", auxfirstName);
        pStudents[nStudents - 1].firstName = (char*)malloc(strlen(auxfirstName) + 1);
        strcpy(pStudents[nStudents - 1].firstName, auxfirstName);

        printf("Last Name: ");
        scanf("%s", auxlastName);
        pStudents[nStudents - 1].lastName = (char*)malloc(strlen(auxlastName) + 1);
        strcpy(pStudents[nStudents - 1].lastName, auxlastName);

        printf("Grade: ");
        scanf("%f", &auxGrade);
        pStudents[nStudents - 1].grade = auxGrade;
        i++;
        rewriteFile(pStudents, nStudents);
        printf("\n  Enter Another Choice : ");
        break;


    case '2':
        int idtoUpdate;
        printf("Update Records for student number: ");
        scanf("%d", &idtoUpdate);
        idtoUpdate = idtoUpdate - 1;
        if (idtoUpdate>nStudents)
            printf("Your number is bigger than number of Students. Enter a correct number.");
        else
        {
            int auxI = idtoUpdate;
            printf("\n");
            printf("Change details for student number %d. \n", auxI + 1);
            printf("type 1 for Yes / type 0 for Next step\n");

            int changeChoice = 0, changeCount;
            printf("Want to change First name?:");
            scanf("%d", &changeChoice);
            changeCount = 0;
            if (changeChoice == 1)
            {
                changeCount++;
                printf("Change First name: ");
                scanf("%s", auxfirstName);
                pStudents[auxI].firstName = (char*)malloc(strlen(auxfirstName) + 1);
                strcpy(pStudents[auxI].firstName, auxfirstName);
            }

            changeChoice = 0;
            printf("Want to change Last name?:");
            scanf("%d", &changeChoice);
            if (changeChoice == 1)
            {
                changeCount++;
                printf("Change Last Name: ");
                scanf("%s", auxlastName);
                pStudents[auxI].lastName = (char*)malloc(strlen(auxlastName) + 1);
                strcpy(pStudents[auxI].lastName, auxlastName);
            }

            changeChoice = 0;
            printf("Want to change the Grade?:");
            scanf("%d", &changeChoice);
            if (changeChoice == 1)
            {
                updGrade = 0;
                changeCount++;
                printf("Change Grade: ");
                scanf(" %f", &updGrade);
                pStudents[auxI].grade = updGrade;
            }
            if (changeCount != 0)
                rewriteFile(pStudents, nStudents);
        }
        printf("\n  Enter Another Choice : ");
        break;

    case '3':
        int idtoDelete;
        printf("Delete Records for student number: ");
        scanf("%d", &idtoDelete);
        idtoDelete = idtoDelete - 1;
        if (idtoDelete>nStudents)
            printf("Your number is bigger than number of Students. Enter a correct number.");
        else
        {
            for (int i = idtoDelete; i < nStudents - 1; ++i)
            {
                strcpy(pStudents[i].firstName, pStudents[i + 1].firstName);
                strcpy(pStudents[i].lastName, pStudents[i + 1].lastName);
                pStudents[i].grade = pStudents[i + 1].grade;
            }
            free(pStudents[nStudents-1].firstName);
            free(pStudents[nStudents - 1].lastName);
            nStudents--;

            rewriteFile(pStudents, nStudents);
        }
        printf("\n  Enter Another Choice : ");
        break;

    case '4':
        char str[10];
        printf("\n Enter the filename (max. 10 characters): ");
        scanf("%s", str);
        exportCSV(str, pStudents, nStudents);
        printf("\n  Enter Another Choice : ");
        break;

    case '5':
        printf("\n");
        for (int i = 0; i < nStudents - 1; ++i)
            for (int j = i + 1; j < nStudents; ++j)
            {
                if (pStudents[i].grade > pStudents[j].grade)
                {
                    StudentDynamic aux;
                    aux = pStudents[i];
                    pStudents[i] = pStudents[j];
                    pStudents[j] = aux;
                }
            }
        printStudents(pStudents, nStudents);
        printf("\n  Enter Another Choice : ");
        break;

    case '6':
        for (int i = 0; i < nStudents-1; ++i)
        {
            free(pStudents[i].firstName);
            free(pStudents[i].lastName);
        }
        free(pStudents);

        printf("\n");
        printf("\t\t     Thank you for using my application.");
        printf("\n\n");
        exit(0);
    }
    }
    return 0;
    }

最佳答案

在一个地方分配额外的记录时,使用:

    pStudents = (StudentDynamic*)realloc(pStudents, sizeof(StudentDynamic)*(i + 2));


我认为您在其中创建了太多记录,应该是i +1

稍后在您使用的代码中

    pStudents = (StudentDynamic*)realloc(pStudents, sizeof(StudentDynamic) * (nStudents + 1));


并且看起来是正确的。因为这是您遇到问题的最后一个学生记录,所以这就是问题所在,当读取文件时,最后会有一条额外的记录。您在数组末尾的任何内容中都没有多余的记录。

关于c - 在C中正常阻塞后检测到堆损坏,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48213749/

10-11 23:07