C中malloc引起的内存泄漏
Memory leaks caused by malloc in C
我很难理解我的代码中出了什么问题。我的程序有一个 函数,它一次从文件中读取 8 个字节的数据。
char *read_64_bit_data_from_file(FILE *file, size_t *number_of_chars_read ){
char *buffer = malloc(sizeof(char) * 8);
*number_of_chars_read = fread(buffer, 1, 8, file);
printf("%s\n", buffer);
printf("Length of buffer: %ld\n", strlen(buffer));
printf("Number of chars read: %ld\n", *number_of_chars_read);
return buffer;
}
函数调用如下:
...
size_t num = 0;
size_t *number_of_chars_read = #
char *message = calloc(sizeof(char), 8);
do{
message = read_64_bit_data_from_file(file, number_of_chars_read);
}while(*number_of_chars_read==8);
...
现在,当我编译 运行 程序时,我得到以下输出:
Two road�B�z
Length of buffer: 14
Number of chars read: 8
s divergx<�z
Length of buffer: 14
Number of chars read: 8
ed in a x<�z
Length of buffer: 14
Number of chars read: 8
yellow wx<�z
Length of buffer: 14
Number of chars read: 8
ood, Andx<�z
Length of buffer: 14
Number of chars read: 8
sorry I
Length of buffer: 8
Number of chars read: 8
could n
Length of buffer: 8
Number of chars read: 8`
问题是写入缓冲区的字符有时会超过8个,虽然fread
returns值8 每次。
现在,如果我使用 calloc
而不是 malloc
来分配 buffer
,我将得到所需的输出 。以下是这种情况下的输出:
Two road
Length of buffer: 8
Number of chars read: 8
s diverg
Length of buffer: 8
Number of chars read: 8
ed in a
Length of buffer: 8
Number of chars read: 8
yellow w
Length of buffer: 8
Number of chars read: 8
ood, And
Length of buffer: 8
Number of chars read: 8
sorry I
Length of buffer: 8
Number of chars read: 8
could n
Length of buffer: 8
Number of chars read: 8`
我使用带有 -Wall
和 -Wextra
标志的 GCC 编译器编译我的程序。
编译器没有给出警告。
我运行程序通过valgrind
。以下是输出:
==6051== Invalid write of size 1
==6051== at 0x10917B: char_as_binary (in
/home/saksham/Documents/DES/DES)
==6051== by 0x1091FA: string_to_binary (in
/home/saksham/Documents/DES/DES)
==6051== by 0x108EE6: main (in /home/saksham/Documents/DES/DES)
==6051== Address 0x521ecf7 is 5 bytes after a block of size 2 alloc'd
==6051== at 0x4C31B25: calloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6051== by 0x1090EE: char_as_binary (in
/home/saksham/Documents/DES/DES)
==6051== by 0x1091FA: string_to_binary (in
/home/saksham/Documents/DES/DES)
==6051== by 0x108EE6: main (in /home/saksham/Documents/DES/DES)
==6051==
==6051== Invalid read of size 1
==6051== at 0x10900A: initial_permutation (in
/home/saksham/Documents/DES/DES)
==6051== by 0x108FA9: encrypt (in /home/saksham/Documents/DES/DES)
==6051== by 0x108EFD: main (in /home/saksham/Documents/DES/DES)
==6051== Address 0x521ec60 is 0 bytes after a block of size 64
alloc'd
==6051== at 0x4C31B25: calloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6051== by 0x1091D3: string_to_binary (in
/home/saksham/Documents/DES/DES)
==6051== by 0x108EE6: main (in /home/saksham/Documents/DES/DES)
==6051==
==6051==
==6051== HEAP SUMMARY:
==6051== in use at exit: 2,076 bytes in 172 blocks
==6051== total heap usage: 186 allocs, 14 frees, 12,972 bytes
allocated
==6051==
==6051== LEAK SUMMARY:
==6051== definitely lost: 2,076 bytes in 172 blocks
==6051== indirectly lost: 0 bytes in 0 blocks
==6051== possibly lost: 0 bytes in 0 blocks
==6051== still reachable: 0 bytes in 0 blocks
==6051== suppressed: 0 bytes in 0 blocks
==6051== Rerun with --leak-check=full to see details of leaked memory
==6051==
==6051== For counts of detected and suppressed errors, rerun with: -v
==6051== ERROR SUMMARY: 93 errors from 2 contexts (suppressed: 0 from
0)
我真的不明白为什么 malloc 会这样,以及如何使用 calloc 修复它。我相信我的程序有 UB(未定义行为)。
请帮助我了解我正在监督的内容以及我哪里出错了。
为了让C-string风格的函数起作用(比如strlen
),你需要在buffer
中预留一个字节给NUL-terminator。
你没有这样做,所以你的程序的行为正式是未定义。您的编译器没有接受这一点,但 Valgrind 是。它还会警告您缺少 free
。考虑分配 9 个字节,将 buffer[8]
显式设置为 0
,并确保您不尝试将超过 8 个字节读入 buffer
.
我很难理解我的代码中出了什么问题。我的程序有一个 函数,它一次从文件中读取 8 个字节的数据。
char *read_64_bit_data_from_file(FILE *file, size_t *number_of_chars_read ){
char *buffer = malloc(sizeof(char) * 8);
*number_of_chars_read = fread(buffer, 1, 8, file);
printf("%s\n", buffer);
printf("Length of buffer: %ld\n", strlen(buffer));
printf("Number of chars read: %ld\n", *number_of_chars_read);
return buffer;
}
函数调用如下:
...
size_t num = 0;
size_t *number_of_chars_read = #
char *message = calloc(sizeof(char), 8);
do{
message = read_64_bit_data_from_file(file, number_of_chars_read);
}while(*number_of_chars_read==8);
...
现在,当我编译 运行 程序时,我得到以下输出:
Two road�B�z
Length of buffer: 14
Number of chars read: 8
s divergx<�z
Length of buffer: 14
Number of chars read: 8
ed in a x<�z
Length of buffer: 14
Number of chars read: 8
yellow wx<�z
Length of buffer: 14
Number of chars read: 8
ood, Andx<�z
Length of buffer: 14
Number of chars read: 8
sorry I
Length of buffer: 8
Number of chars read: 8
could n
Length of buffer: 8
Number of chars read: 8`
问题是写入缓冲区的字符有时会超过8个,虽然fread
returns值8 每次。
现在,如果我使用 calloc
而不是 malloc
来分配 buffer
,我将得到所需的输出 。以下是这种情况下的输出:
Two road
Length of buffer: 8
Number of chars read: 8
s diverg
Length of buffer: 8
Number of chars read: 8
ed in a
Length of buffer: 8
Number of chars read: 8
yellow w
Length of buffer: 8
Number of chars read: 8
ood, And
Length of buffer: 8
Number of chars read: 8
sorry I
Length of buffer: 8
Number of chars read: 8
could n
Length of buffer: 8
Number of chars read: 8`
我使用带有 -Wall
和 -Wextra
标志的 GCC 编译器编译我的程序。
编译器没有给出警告。
我运行程序通过valgrind
。以下是输出:
==6051== Invalid write of size 1
==6051== at 0x10917B: char_as_binary (in
/home/saksham/Documents/DES/DES)
==6051== by 0x1091FA: string_to_binary (in
/home/saksham/Documents/DES/DES)
==6051== by 0x108EE6: main (in /home/saksham/Documents/DES/DES)
==6051== Address 0x521ecf7 is 5 bytes after a block of size 2 alloc'd
==6051== at 0x4C31B25: calloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6051== by 0x1090EE: char_as_binary (in
/home/saksham/Documents/DES/DES)
==6051== by 0x1091FA: string_to_binary (in
/home/saksham/Documents/DES/DES)
==6051== by 0x108EE6: main (in /home/saksham/Documents/DES/DES)
==6051==
==6051== Invalid read of size 1
==6051== at 0x10900A: initial_permutation (in
/home/saksham/Documents/DES/DES)
==6051== by 0x108FA9: encrypt (in /home/saksham/Documents/DES/DES)
==6051== by 0x108EFD: main (in /home/saksham/Documents/DES/DES)
==6051== Address 0x521ec60 is 0 bytes after a block of size 64
alloc'd
==6051== at 0x4C31B25: calloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6051== by 0x1091D3: string_to_binary (in
/home/saksham/Documents/DES/DES)
==6051== by 0x108EE6: main (in /home/saksham/Documents/DES/DES)
==6051==
==6051==
==6051== HEAP SUMMARY:
==6051== in use at exit: 2,076 bytes in 172 blocks
==6051== total heap usage: 186 allocs, 14 frees, 12,972 bytes
allocated
==6051==
==6051== LEAK SUMMARY:
==6051== definitely lost: 2,076 bytes in 172 blocks
==6051== indirectly lost: 0 bytes in 0 blocks
==6051== possibly lost: 0 bytes in 0 blocks
==6051== still reachable: 0 bytes in 0 blocks
==6051== suppressed: 0 bytes in 0 blocks
==6051== Rerun with --leak-check=full to see details of leaked memory
==6051==
==6051== For counts of detected and suppressed errors, rerun with: -v
==6051== ERROR SUMMARY: 93 errors from 2 contexts (suppressed: 0 from
0)
我真的不明白为什么 malloc 会这样,以及如何使用 calloc 修复它。我相信我的程序有 UB(未定义行为)。
请帮助我了解我正在监督的内容以及我哪里出错了。
为了让C-string风格的函数起作用(比如strlen
),你需要在buffer
中预留一个字节给NUL-terminator。
你没有这样做,所以你的程序的行为正式是未定义。您的编译器没有接受这一点,但 Valgrind 是。它还会警告您缺少 free
。考虑分配 9 个字节,将 buffer[8]
显式设置为 0
,并确保您不尝试将超过 8 个字节读入 buffer
.