这是一个用于管理停车场的 C 脚本,我有这个结构:
typedef struct {
char name[MAXSIZE];
int capacity;
char car_plates[MAXREGISTRATIONS][PLATE_SIZE];
char entry_dates[MAXREGISTRATIONS][DATE_SIZE];
char entry_hours[MAXREGISTRATIONS][HOUR_SIZE];
char exit_date[DATE_SIZE];
char exit_hour[HOUR_SIZE];
float value_15_minutes;
float value_after_1_hour;
float max_daily_value;
float revenue;
int available_spaces;
} ParkingLot;
int num_parks = 0;
ParkingLot parks[MAXPARKS];
我有一个名为“创建公园”的功能,效果很好:
void createParking(char name[], int capacity, float value_15_minutes, float value_after_1_hour, float max_daily_value) {
if (num_parks >= MAXPARKS) {
printf("Too many parks.\n");
return;
}
for (int i = 0; i < num_parks; i++) {
if (strcmp(parks[i].name, name) == 0) {
printf("%s: Parking already exists.\n", name);
return;
}
}
if(capacity <= 0){
printf("%d: Invalid capacity.\n", capacity);
return;
}
if (value_15_minutes <= 0 || value_after_1_hour <= value_15_minutes || max_daily_value <= value_after_1_hour) {
printf("Invalid cost.\n");
return;
}
strcpy(parks[num_parks].name, name);
parks[num_parks].capacity = capacity;
parks[num_parks].value_15_minutes = value_15_minutes;
parks[num_parks].value_after_1_hour = value_after_1_hour;
parks[num_parks].max_daily_value = max_daily_value;
parks[num_parks].available_spaces = capacity;
num_parks++;
}
所以这只是为了上下文,该函数不是问题,问题是我的代码中出现内存泄漏,考虑到我有零个 malloc,我认为这很奇怪。这是 Valgrind 报告,以及所有函数已发行
==3537366== 4,096 bytes in 1 block are still reachable in loss record 32 of 32
==3537366== at 0x4843828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==3537366== by 0x48D6633: _IO_file_doallocate (filedoalloc.c:101)
==3537366== by 0x48E65AF: _IO_doallocbuf (genops.c:347)
==3537366== by 0x48E550F: _IO_file_overflow@@GLIBC_2.2.5 (fileops.c:744)
==3537366== by 0x48E3CE4: _IO_new_file_xsputn (fileops.c:1243)
==3537366== by 0x48E3CE4: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1196)
==3537366== by 0x48B4AA0: __printf_buffer_flush_to_file (printf_buffer_to_file.c:59)
==3537366== by 0x48B4AA0: __printf_buffer_to_file_done (printf_buffer_to_file.c:120)
==3537366== by 0x48BEB48: __vfprintf_internal (vfprintf-internal.c:1460)
==3537366== by 0x498B63A: __printf_chk (printf_chk.c:33)
==3537366== by 0x10C6F8: printf (stdio2.h:86)
==3537366== by 0x10C6F8: list_parks (project.c:429)
==3537366== by 0x10C6F8: command_p (project.c:978)
==3537366== by 0x109377: main (project.c:1275)
int main() {
while (1) {
char command[50];
scanf("%s", command);
if (strcmp(command, "q") == 0) {
release_daily_revenue(&daily_revenue);
break;
}
check_input(command);
}
return 0;
}
void command_p(char command[]) {
int rc;
char name[MAXSIZE];
float capacity;
float value_15, value_15_after_1_hour, max_daily_value;
if (strcmp(command, "p") == 0) {
char nextChar = getchar();
if (nextChar == '\n') {
list_parks();
} else {
ungetc(nextChar, stdin);
char str[MAXSIZE * 5]; // Increasing the size to handle complete input
if (fgets(str, MAXSIZE * 5, stdin) == NULL) {
return;
}
if ((rc = sscanf(str, "%s %f %f %f %f", name, &capacity, &value_15, &value_15_after_1_hour, &max_daily_value)) != 5) {
rc = sscanf(str, " \"%[^\"]\" %f %f %f %f", name, &capacity, &value_15, &value_15_after_1_hour, &max_daily_value);
createParking(name, (int)capacity, value_15, value_15_after_1_hour, max_daily_value);
}
}
}
void list_parks() {
for (int i = 0; i < num_parks; i++) {
printf("%s %d %d\n", parks[i].name, parks[i].capacity, parks[i].available_spaces);
}
return;
}
valgrind 报告说我在 list_parks 函数中的 1 个块中丢失了 4096 个字节,我无法理解这是如何发生的,并且另外丢失了 4096 个字节(仍然可达),总共 164 个块中的 10,553 个字节(一些其余代码中的其他小泄漏)。你能帮我弄清楚这里到底发生了什么吗
鉴于最近 liblzma 的崩溃,不要急于听人们说问题是误报。
“最小可重现示例”也不能替代了解 Valgrind 的工作原理。
评论是正确的,这是 GNU libc 为 I/O 缓冲完成的一次性分配。由于某种原因(也许您使用的 Valgrind 版本太旧),Valgrind 没有运行 glibc 清理功能。您的 glibc 也可能存在缺陷,并且它没有使用 __libc_freeres 释放内存。
如果你运行
valgrind -v -v [your exe]
你应该看到类似的东西
--16708-- Caught __NR_exit; running __gnu_cxx::__freeres and __libc_freeres() wrapper
如果没有您的操作系统、编译器和 Valgrind 版本的更多详细信息,我无法说出原因