C语言代码内存泄漏排查求助:Valgrind检测到8块内存未释放
Let's walk through the issues causing your Valgrind-reported leaks and fix them one by one—you're really close, just a couple of small bugs tripping you up!
1. Critical Bug in destroy_student_array
The biggest culprit is a backwards loop condition that completely skips freeing any student names in your array:
void destroy_student_array(struct student* students, int num_students) { // ❌ This condition is wrong—0 is never greater than num_students, so the loop never runs for (int i = 0; i > num_students; i++) { free_student(&students[i]); } free(students); }
Fix:
Change the loop condition to i < num_students so it iterates over every student in the array:
void destroy_student_array(struct student* students, int num_students) { for (int i = 0; i < num_students; i++) { free_student(&students[i]); } free(students); }
This will properly call free_student on each student, releasing the name memory allocated by init_student. This directly fixes the 8 blocks of leaked memory reported by Valgrind (one per student in your test dataset).
2. Minor Robustness Fix in main
In your main function, you correctly free the copied student, but adding a NULL check will prevent undefined behavior if deep_copy_student ever fails (unlikely here, but good practice):
// Before free_student(copy); free(copy); // After if (copy != NULL) { free_student(copy); free(copy); }
3. Quick Confirmation: No Leaks from the Stack Student
You correctly call free_student(&student) for the stack-allocated student in main, so that memory is properly freed—no issues there.
Verify the Fix
After making these changes, re-run Valgrind and you should see a clean bill of health:
==XXXX== HEAP SUMMARY: ==XXXX== in use at exit: 0 bytes in 0 blocks ==XXXX== total heap usage: 12 allocs, 12 frees, 262 bytes allocated ==XXXX== ==XXXX== All heap blocks were freed -- no leaks are possible
Bonus: A Note on sort_by_gpa
Your sorting function uses direct struct assignment (temp = students[j];), which is safe here! You're just swapping pointers within the same array, so the original memory for each name is still tracked by the array elements. When you call destroy_student_array, all names will still be freed correctly—no issues here.
内容的提问来源于stack exchange,提问作者Chris

