これまでのところ私のプログラムはかなりうまく動いていましたが、valgrindを実行してフリー/ mallocを忘れていないことを確認しました。しかしValgrindはエラーがないと私は信じています。ここでreallocとstrdupを使って割り振ったときに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 &この回答については、通常、人々はnullバイトを割り当てることを忘れてしまいます。
メモリが残っていないときにreallocがメモリリークを引き起こす可能性があることがわかっています。まず、reallocの結果を一時変数に代入し、戻り値がnullでないことを確認してから、
reallocが失敗した場合のリークの可能性がありますが、このプログラムに間違いがありますか?迅速な答えを
UPDATE
みんなありがとう。あなたのすべてに
==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)
良い一日:
/* 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の出力:ここではレコードの
は修正されたコードです。この(第2)の呼び出しで
2回目のreallocは配列のサイズを増やしません。 –
'name_array = realloc(name_array、sizeof(char *));' => 'name_array = realloc(name_array、sizeof * name_array * ++ nb_names);'。 – Stargateur
また、 'name_array = realloc(name_array、...)'は潜在的なメモリリークです。 'malloc()'が 'NULL'を返さなかったことを確認してください。 –