Skip to main content
 首页 » 编程设计

c之valgrind 报告错误并且在使用 realloc() 时肯定会丢失

2023年11月22日26shangdawei

以下是两个函数,其中第一个尝试根据计数值为指针数组分配并随后重新分配内存。

第二个函数尝试将指针数组中的最后一个字符串连接到第一个字符串。

程序将字符串的数量和要匹配的模式作为命令行参数,仅当在输入字符串中找到匹配模式时才调用第一个函数。

20  char **allocate_array_of_ptrs(char **str_array, /* pointer to the array of pointers */ 
21                      char *str,              /* pointer to the input string */ 
22                      int count)              /* count of matched strings */ 
23  { 
24          char **temp = NULL;           /*      temporary pointer to realloc memory */ 
25 
26          /* realloc based on count value */ 
27          temp = (char **)realloc(str_array, count * sizeof(char *)); 
28 
29          int str_len = strlen(str); 
30 
31          /* if realloc is successful */ 
32          if (NULL != temp) 
33          { 
34                  str_array = temp; 
35 
36                  /* alloc memory for the string to be stored */ 
37                  temp[count - 1] = (char *)calloc((str_len + 1), sizeof(char)); 
38                  strcpy(temp[count - 1], str); 
39          } 
40 
41          return str_array; 
42  } 
43 
44  char **dmm_str_cat(char **str_array,          /* pointer to the array of pointers */ 
45                int count)                      /* count of matched strings */ 
46  { 
47          int i;                                          /* iterator */ 
48          int total_str_len = 0;      /* total length when all strings put together */ 
49          int str_len_of_first;       /* string length of first string in the array */ 
50 
51          if (count > 1) 
52          { 
53                  str_len_of_first = strlen(str_array[0]); 
54 
55                  for (i = 0; i < count; i++) 
56                  { 
57                          total_str_len += strlen(str_array[i]); 
58                  } 
59                  total_str_len += 1; 
60 
61              /* realloc memory to accomodate all matched strings onto first string */ 
62           str_array[0] = (char *)realloc(str_array[0], total_str_len * sizeof(char)); 
63 
64                  /* clearing the new allocated bytes */ 
65                  for (i = (str_len_of_first + 1); i < total_str_len; i++) 
66                  { 
67                          str_array[0][i] = '\0'; 
68                  } 
69 
70                  /* concatenate from the last string onwards onto first string */ 
71                  for (i = count - 1; i > 0; i--) 
72                  { 
73                          strcat(str_array[0], str_array[i]); 
74                  } 
75          } 
76 
77          return str_array; 
78  } 

问题是当代码在 valgrind 下运行时,当在 3 个字符串中有 2 个字符串与模式 'el' 不匹配时,它会报告以下消息。其他组合也会报告类似的错误。

        Enter string 1 : matter 
 
        Enter string 2 : matter 
 
        Enter string 3 : jello 
 
        Count of strings having matching pattern 'el' : 1 
        The matching strings are : 
                jello 
==6244== Invalid read of size 8 
==6244==    at 0x400A74: main (dmm_main.c:86) 
==6244==  Address 0x4C33038 is 0 bytes after a block of size 8 alloc'd 
==6244==    at 0x4A05809: malloc (vg_replace_malloc.c:149) 
==6244==    by 0x4A05883: realloc (vg_replace_malloc.c:306) 
==6244==    by 0x400AE9: allocate_array_of_ptrs (dmm_functions.c:27) 
==6244==    by 0x4009B6: main (dmm_main.c:64) 
==6244== 
==6244== Invalid write of size 8 
==6244==    at 0x400A89: main (dmm_main.c:87) 
==6244==  Address 0x4C33038 is 0 bytes after a block of size 8 alloc'd 
==6244==    at 0x4A05809: malloc (vg_replace_malloc.c:149) 
==6244==    by 0x4A05883: realloc (vg_replace_malloc.c:306) 
==6244==    by 0x400AE9: allocate_array_of_ptrs (dmm_functions.c:27) 
==6244==    by 0x4009B6: main (dmm_main.c:64) 
        The concatenated string is : jello==6244== 
==6244== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 4 from 1) 
==6244== malloc/free: in use at exit: 0 bytes in 0 blocks. 
==6244== malloc/free: 2 allocs, 2 frees, 14 bytes allocated. 
==6244== For counts of detected errors, rerun with: -v 
==6244== All heap blocks were freed -- no leaks are possible. 

但是当有两个字符串与模式匹配而一个不匹配时,valgrind 就不会报告任何错误/泄漏。当所有字符串都匹配该模式时,就会报告 definitely lost。

请您参考如下方法:

考虑到您有一个无效的读取后跟一个无效的写入,我敢打赌传递给 allocate_array_of_ptrsstr_array 没有正确初始化-

实际上,在大小为 8 的 block 分配后的消息 0 字节 让我认为您超出了数组的大小,但如果没有 main.c 代码,我不能 100% 确定。