gpt4 book ai didi

c - C 中正常 block 后检测到堆损坏

转载 作者:行者123 更新时间:2023-11-30 16:36:58 25 4
gpt4 key购买 nike

我有一个数据库应用程序,在添加和删除一些记录后,我进入案例 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 中正常 block 后检测到堆损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48213749/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com