为什么我会丢失“3,744,768 字节”的内存?
Why am I losing `3,744,768 bytes` of memory?
我是编程新手,我正在编写一个程序来通过比较 4 个连续字节来恢复“card.raw”中存在的 JPEG 文件。如果他们划分了 JPEG,程序必须将 512 字节的块复制到保存为 xxx.jpg(000.jpg、001.jpg 等)的新文件中。如果复制完该块后,找到新JPEG的开头,则关闭当前文件并打开下一个文件复制下一个JPG。否则下一个块将被复制到同一个文件中。
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int counter = 0;
if(argc != 2)
{
printf("Usage: ./recover image\n");
return 1;
}
typedef uint8_t BYTE;
FILE *recover = fopen(argv[1], "r");
if(recover == NULL)
{
printf("ERRNO 1 IS %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
fseek(recover, 0L, SEEK_END);
unsigned long size = ftell(recover);
fseek(recover, 0L, SEEK_SET);
BYTE *CHUNK = (BYTE*)malloc(size * sizeof(BYTE));
fread(CHUNK, sizeof(BYTE), size, recover); //Break recover into bytes
int j = 0;
char file[8] = "xxx.jpg";
FILE *f = NULL;
int s = 0;
while(j < size)
{
if(CHUNK[j] == 0xff && CHUNK[j + 1] == 0xd8 && CHUNK[j + 2] == 0xff) //Check if byte is JPEG format 1st byte
{
if(s == 0)
{
if(f != NULL)
{
f = NULL;
}
sprintf(file ,"%03d.jpg",counter); //Create custom file of format xxx.jpg
f = fopen(file,"w");
if(f == NULL)
{
printf("ERRNO 2 is %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
fwrite(&CHUNK[j], 512, sizeof(BYTE), f); //Copy 512 bytes from start of JPEG file as 512 bytes form one 'block`
j += 512; //Increment to check initial bytes of next 'block'
s++;
}
else
{
fclose(f);
counter++;
s = 0;
}
}
else if(s > 0) //Else continue searching
{
fwrite(&CHUNK[j], 512, sizeof(BYTE), f);
j += 512;
}
else j += 512;
}
fclose(f);
fclose(recover);
free(&CHUNK);
return 0;
}
除了 Valgrind
给我以下报告外,该程序运行完美:
==1560== Memcheck, a memory error detector
==1560== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1560== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==1560== Command: ./recover card.raw
==1560==
==1560== Invalid free() / delete / delete[] / realloc()
==1560== at 0x4C32D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1560== by 0x400BF4: main (recover.c:69)
==1560== Address 0x1fff000510 is on thread 1's stack
==1560== in frame #1, created by main (recover.c:9)
==1560==
==1560==
==1560== HEAP SUMMARY:
==1560== in use at exit: 3,744,768 bytes in 1 blocks
==1560== total heap usage: 103 allocs, 103 frees, 3,981,816 bytes allocated
==1560==
==1560== 3,744,768 bytes in 1 blocks are definitely lost in loss record 1 of 1
==1560== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1560== by 0x4009FA: main (recover.c:26)
==1560==
==1560== LEAK SUMMARY:
==1560== definitely lost: 3,744,768 bytes in 1 blocks
==1560== indirectly lost: 0 bytes in 0 blocks
==1560== possibly lost: 0 bytes in 0 blocks
==1560== still reachable: 0 bytes in 0 blocks
==1560== suppressed: 0 bytes in 0 blocks
==1560==
==1560== For counts of detected and suppressed errors, rerun with: -v
==1560== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Valgrind
似乎说问题出在 line 26
:
中的内存分配
BYTE *CHUNK = (BYTE*)malloc(size * sizeof(BYTE));
但是我在最后用free(&CHUNK);
释放了分配的内存。我想知道为什么 Valgrind
报告说 3,744,768 bytes in 1 blocks
已经 definitely lost
。
free(&CHUNK)
要求 free
space 用于 变量 CHUNK
,即(例如 4 或 8 ) 指针本身占用的字节;除了不释放你正在考虑的内存之外,这是未定义的行为,因为你可以 free
只有 malloc
和朋友分配的内存,我很惊讶你没有因为在分配器内部进行一些完整性检查。
你实际需要做的是释放指向 CHUNK
的内存,所以你必须做free(CHUNK)
.
我是编程新手,我正在编写一个程序来通过比较 4 个连续字节来恢复“card.raw”中存在的 JPEG 文件。如果他们划分了 JPEG,程序必须将 512 字节的块复制到保存为 xxx.jpg(000.jpg、001.jpg 等)的新文件中。如果复制完该块后,找到新JPEG的开头,则关闭当前文件并打开下一个文件复制下一个JPG。否则下一个块将被复制到同一个文件中。
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int counter = 0;
if(argc != 2)
{
printf("Usage: ./recover image\n");
return 1;
}
typedef uint8_t BYTE;
FILE *recover = fopen(argv[1], "r");
if(recover == NULL)
{
printf("ERRNO 1 IS %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
fseek(recover, 0L, SEEK_END);
unsigned long size = ftell(recover);
fseek(recover, 0L, SEEK_SET);
BYTE *CHUNK = (BYTE*)malloc(size * sizeof(BYTE));
fread(CHUNK, sizeof(BYTE), size, recover); //Break recover into bytes
int j = 0;
char file[8] = "xxx.jpg";
FILE *f = NULL;
int s = 0;
while(j < size)
{
if(CHUNK[j] == 0xff && CHUNK[j + 1] == 0xd8 && CHUNK[j + 2] == 0xff) //Check if byte is JPEG format 1st byte
{
if(s == 0)
{
if(f != NULL)
{
f = NULL;
}
sprintf(file ,"%03d.jpg",counter); //Create custom file of format xxx.jpg
f = fopen(file,"w");
if(f == NULL)
{
printf("ERRNO 2 is %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
fwrite(&CHUNK[j], 512, sizeof(BYTE), f); //Copy 512 bytes from start of JPEG file as 512 bytes form one 'block`
j += 512; //Increment to check initial bytes of next 'block'
s++;
}
else
{
fclose(f);
counter++;
s = 0;
}
}
else if(s > 0) //Else continue searching
{
fwrite(&CHUNK[j], 512, sizeof(BYTE), f);
j += 512;
}
else j += 512;
}
fclose(f);
fclose(recover);
free(&CHUNK);
return 0;
}
除了 Valgrind
给我以下报告外,该程序运行完美:
==1560== Memcheck, a memory error detector
==1560== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1560== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==1560== Command: ./recover card.raw
==1560==
==1560== Invalid free() / delete / delete[] / realloc()
==1560== at 0x4C32D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1560== by 0x400BF4: main (recover.c:69)
==1560== Address 0x1fff000510 is on thread 1's stack
==1560== in frame #1, created by main (recover.c:9)
==1560==
==1560==
==1560== HEAP SUMMARY:
==1560== in use at exit: 3,744,768 bytes in 1 blocks
==1560== total heap usage: 103 allocs, 103 frees, 3,981,816 bytes allocated
==1560==
==1560== 3,744,768 bytes in 1 blocks are definitely lost in loss record 1 of 1
==1560== at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1560== by 0x4009FA: main (recover.c:26)
==1560==
==1560== LEAK SUMMARY:
==1560== definitely lost: 3,744,768 bytes in 1 blocks
==1560== indirectly lost: 0 bytes in 0 blocks
==1560== possibly lost: 0 bytes in 0 blocks
==1560== still reachable: 0 bytes in 0 blocks
==1560== suppressed: 0 bytes in 0 blocks
==1560==
==1560== For counts of detected and suppressed errors, rerun with: -v
==1560== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Valgrind
似乎说问题出在 line 26
:
BYTE *CHUNK = (BYTE*)malloc(size * sizeof(BYTE));
但是我在最后用free(&CHUNK);
释放了分配的内存。我想知道为什么 Valgrind
报告说 3,744,768 bytes in 1 blocks
已经 definitely lost
。
free(&CHUNK)
要求 free
space 用于 变量 CHUNK
,即(例如 4 或 8 ) 指针本身占用的字节;除了不释放你正在考虑的内存之外,这是未定义的行为,因为你可以 free
只有 malloc
和朋友分配的内存,我很惊讶你没有因为在分配器内部进行一些完整性检查。
你实际需要做的是释放指向 CHUNK
的内存,所以你必须做free(CHUNK)
.