提问人:Savvidaios 提问时间:9/21/2023 更新时间:9/21/2023 访问量:39
即使在释放 C 语言中的 malloc 空间后,Valgrind 也能检测到可访问的块(cs50 问题集 4 恢复)
Valgrind detects reachable blocks even after freeing malloc space in C (cs50 Problem Set 4 Recover)
问:
我已经完成了 cs50 的问题集 4 称为 recover。您将在下面看到我已将 malloc 用于名为 sfile 的 char*。在文件的末尾,我记得释放分配的空间(又名 sfile)并关闭我打开的 2 个文档。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
if (argc != 2)
{
printf("Usage: ./recover IMAGE\n");
return 1;
}
printf("%s", argv[1]);
FILE *file = fopen(argv[1], "r");
if (file == NULL)
{
printf(" can't be opened for reading\n");
return 2;
}
unsigned char arr[512];
int s = 0;
FILE *output_file = NULL;
char *sfile = malloc(sizeof(char) * 8);
while (fread(arr, sizeof(char), 512, file) != 0)
{
if (arr[0] == 0xff && arr[1] == 0xd8 && arr[2] == 0xff && (arr[3] & 0xf0) == 0xe0)
{
sprintf(sfile, "%03i.jpg", s);
output_file = fopen(sfile, "w");
s++;
}
if (output_file != NULL)
{
fwrite(arr, sizeof(char), 512, output_file);
}
}
free(sfile);
fclose(output_file);
fclose(file);
return 0;
}
但是,当运行 check50 时,这是一个检查您是否完成了练习的所有要点的工具,我只收到一条红色消息,表明 valgrind 检测到内存错误。所以我的下一步是运行:
$ valgrind ./recover card.raw
这是返回的内容:
==53590== HEAP SUMMARY:
==53590== in use at exit: 23,128 bytes in 49 blocks
==53590== total heap usage: 1,091 allocs, 1,042 frees, 240,880 bytes allocated
==53590==
==53590== 23,128 bytes in 49 blocks are still reachable in loss record 1 of 1
==53590== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==53590== by 0x4A076CD: __fopen_internal (iofopen.c:65)
==53590== by 0x4A076CD: fopen@@GLIBC_2.2.5 (iofopen.c:86)
==53590== by 0x109304: main (recover.c:37)
==53590==
==53590== LEAK SUMMARY:
==53590== definitely lost: 0 bytes in 0 blocks
==53590== indirectly lost: 0 bytes in 0 blocks
==53590== possibly lost: 0 bytes in 0 blocks
==53590== still reachable: 23,128 bytes in 49 blocks
==53590== suppressed: 0 bytes in 0 blocks
==53590==
==53590== For lists of detected and suppressed errors, rerun with: -s
==53590== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
该程序运行良好,这是剩下的唯一问题。
我看过 cs50 恢复门槛,但没有 valgrind 错误,但我无法真正理解它,因为他的代码在我眼中是意大利面条代码(没有冒犯!!
我还是 C 的新手,拥有 Python 编程背景使我很难理解与内存有关的任何事情,因为 python 更直接。
任何帮助都不胜感激:)
答:
3赞
Some programmer dude
9/21/2023
#1
问题是
output_file = fopen(sfile, "w");
将发生多次。但你只关闭一次。output_file
您需要添加检查以查看是否不是,然后先关闭文件,然后再再次打开它。output_file
NULL
主要提示是泄漏发生在 .这在 Valgrind 输出中很容易看到。fopen
评论
0赞
Savvidaios
9/21/2023
你是完全正确的!我把它改成了: if (output_file == NULL) { output_file = fopen(sfile, “w”); } else { fclose(output_file); output_file = fopen(sfile, “w”); } 而且效果很好!非常感谢!!
0赞
Fe2O3
9/21/2023
@Savvidaios 建议你熟悉一下......可惜该功能需要打开文件...如果它像...freopen()
realloc()
malloc()
1赞
Savvidaios
9/21/2023
@Fe2O3我会检查一下。谢谢!!
评论
char *sfile = malloc(sizeof(char) * 8);
char sfile[8];
char sfile[ 128 ];
512