如何解决块内的内存泄漏?

How to solve this memory leak inside a block?

我有以下功能:

STUDENT *getStudents(size_t *numOfStudents){
  STUDENT *students=malloc(sizeof(STUDENT));
  if(students==NULL){
    fprintf(stderr,"Could not allocate memory. Aborting...\n");
    exit(-1);
  }

  FILE *data=fopen("in/data.txt","r");
  for(register size_t i=0;fscanf(data,"%"SCNd32" %"SCNd8,&students[i].num,&students[i].finalGrade)==2;i++){
    ++(*numOfStudents);
    {
      STUDENT *sTemp=realloc(students,*numOfStudents*sizeof(STUDENT));
      if(sTemp==NULL){
        fprintf(stderr,"Could not allocate memory. Aborting...\n");
        exit(-1);
      }
      students=sTemp;
    }
  }
  --(*numOfStudents);
  {
    STUDENT *sTemp=realloc(students,*numOfStudents*sizeof(STUDENT));
    if(sTemp==NULL){
      fprintf(stderr,"Could not allocate memory. Aborting...\n");
      exit(-1);
    }
    students=sTemp;
  }
  return students;
}

使用 -fsanitize=address 编译,它检测到内存泄漏

in getStudents src/student.c:27

也就是下面一行:

STUDENT *sTemp=realloc(students,*numOfStudents*sizeof(STUDENT));

我以为它会自动释放内存,因为它在一个块中。即使在尝试释放它之后,还是会出现同样的问题。

我该如何解决这个问题?

编辑:

int main(void){
  size_t numOfStudents=1;
  STUDENT *students=getStudents(&numOfStudents);
  printStudents(students,numOfStudents);
  printf("\n================\nMean: %f\n================\n\n",
    (float)getGradeSum(students,numOfStudents)/numOfStudents
  );
  students=removeFailed(students,&numOfStudents);
  printStudents(students,numOfStudents);
  getGradeSum(students,numOfStudents);
  free(students);
  return 0;
}
int32_t getGradeSum(STUDENT *students,size_t numOfStudents){
  if(numOfStudents==1){
    return students[0].finalGrade;
  }
  else{
    return students[numOfStudents-1].finalGrade+getGradeSum(students,numOfStudents-1);
  }
}

如果 students 指向的内存被自动释放(但不是因为 C 中没有这样的东西),那么你将无法 return students 因为你将是 return 悬挂指针。

您的函数所做的是动态分配一个正确大小的数组并将其 return 分配给调用者。这使得调用者有责任调用 free().

Valgrind 只是告诉你 free() 从未在该内存上调用过。


现在您的程序有更多(但不是全部)可用,我猜罪魁祸首实际上是这一行:

students=removeFailed(students,&numOfStudents);

据推测,removeFailed returns 是一个与给定的指针不同的指针,因为它复制了正在传递的数组(的一部分)。由于它不会释放作为参数传递的指针,因此该分配仍然存在。但是,由于您已将 students(在 main 中)的值替换为数组副本的地址,因此您无法再从 main 中释放该内存。所以这肯定是内存泄漏。