到目前为止,我的程序运行得很好,我想运行valgrind以确保我没有忘记任何free / malloc。然而,Valgrind在我认为没有的情况下报告错误。
这是重现错误的代码段:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main()
{
/* Init the array to NULL for realloc */
char **name_array = NULL;
int nb_names =0;
/* Allocate the first name and add it to the array */
name_array = realloc(name_array, sizeof(char *));
name_array[nb_names] = strdup("Hello World!\n");
nb_names++;
/* Allocate the second name and add it to the array */
name_array = realloc(name_array, sizeof(char *));
name_array[nb_names] = strdup("This is a test!\n");
/* Print the names */
printf (name_array[0]);
printf (name_array[1]);
/* Free the strdup'd names and the array */
free(name_array[0]);
free(name_array[1]);
free(name_array);
}
这是程序输出:
Hello World!
This is a test!
这是Valgrind输出:
==31585== Memcheck, a memory error detector
==31585== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==31585== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==31585== Command: ./a.out --leak-check=full
==31585==
==31585== Invalid write of size 4
==31585== at 0x10538: main (in /home/pi/tmp/a.out)
==31585== Address 0x49830a4 is 0 bytes after a block of size 4 alloc'd
==31585== at 0x48358A0: realloc (vg_replace_malloc.c:632)
==31585== by 0x10517: main (in /home/pi/tmp/a.out)
==31585==
Hello World!
==31585== Invalid read of size 4
==31585== at 0x10554: main (in /home/pi/tmp/a.out)
==31585== Address 0x49830a4 is 0 bytes after a block of size 4 alloc'd
==31585== at 0x48358A0: realloc (vg_replace_malloc.c:632)
==31585== by 0x10517: main (in /home/pi/tmp/a.out)
==31585==
This is a test!
==31585== Invalid read of size 4
==31585== at 0x10578: main (in /home/pi/tmp/a.out)
==31585== Address 0x49830a4 is 0 bytes after a block of size 4 alloc'd
==31585== at 0x48358A0: realloc (vg_replace_malloc.c:632)
==31585== by 0x10517: main (in /home/pi/tmp/a.out)
==31585==
==31585==
==31585== HEAP SUMMARY:
==31585== in use at exit: 0 bytes in 0 blocks
==31585== total heap usage: 4 allocs, 4 frees, 39 bytes allocated
==31585==
==31585== All heap blocks were freed -- no leaks are possible
==31585==
==31585== For counts of detected and suppressed errors, rerun with: -v
==31585== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
我已经在其他Q&amp; A中搜索了这个答案,通常人们会忘记分配空字节。
我知道当没有内存时,realloc会导致内存泄漏,我应该首先将realloc的结果分配给临时变量,检查返回的值是否为null然后将临时变量分配给我的真实变量。
在realloc失败时可能发生泄漏的公寓,这个程序有什么错误吗?
更新
谢谢你们的快速回答。
这里的记录是更正后的代码:
/* Allocate the first name and add it to the array */
name_array = realloc(name_array, sizeof(char *) * ++nb_names);
name_array[nb_names -1] = strdup("Hello World!\n");
/* Allocate the second name and add it to the array */
name_array = realloc(name_array, sizeof(char *) * ++nb_names);
name_array[nb_names -1] = strdup("This is a test!\n");
/* Print the names */
printf (name_array[0]);
printf (name_array[1]);
valgrind输出:
==32105== Memcheck, a memory error detector
==32105== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==32105== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==32105== Command: ./a.out
==32105==
Hello World!
This is a test!
==32105==
==32105== HEAP SUMMARY:
==32105== in use at exit: 0 bytes in 0 blocks
==32105== total heap usage: 4 allocs, 4 frees, 43 bytes allocated
==32105==
==32105== All heap blocks were freed -- no leaks are possible
==32105==
==32105== For counts of detected and suppressed errors, rerun with: -v
==32105== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
大家好日子。
答案 0 :(得分:1)
通过此(第二)电话:
name_array = realloc(name_array, sizeof(char *));
您仍然只分配一个字符指针。所以,你不能存储两个指针;你需要增加尺寸:
name_array = realloc(name_array, 2 * sizeof *name_array);
现在,你没事。
请注意,如果p = realloc(p, ..);
失败,realloc()
样式的realloc()可能会导致内存泄漏。
此外,您最好使用格式字符串来避免格式化字符串攻击(如果它将被用户输入):
/* Print the names */
printf ("%s\n", name_array[0]);
printf ("%s\n", name_array[1]);
答案 1 :(得分:0)
地址清理程序报告的错误比valgrind更好。如果您编译代码如下:
gcc test.c -fsanitize=address -g
然后运行它,它将在代码的第19行报告堆缓冲区溢出错误。这是您为name_array分配第二个元素的行,该元素仅为一个元素分配了内存。