Valgrind:无效的读/写大小1问

时间:2017-11-01 07:09:51

标签: c string

我尝试编写一个可以替换字符串中某些单词或字符的代码。虽然输出似乎很好,但使用valgrind时出现了一些错误。有人可以帮忙吗?

01: #include <stdio.h>
02: #include <stdlib.h>
03: #include <string.h>
04: 
05: char *changewords (char *sentence, char *find, char *replace)
06: {
07:     size_t len_total =  0;
08: 
09:     char *dest = malloc (len_total + 1);
10:     char *destptr = dest;
11: 
12:     *dest = 0;
13: 
14:     while (*sentence)
15:     {
16:         if (!strncmp (sentence, find, strlen(find)))
17:         {
18:             len_total += strlen(replace);
19:             dest = realloc(dest, len_total + 1);
20:             *destptr = 0;
21:             strcat (destptr, replace);
22:             sentence += strlen(find);
23:             destptr += strlen(replace);
24:         } else
25:         {
26:             len_total++;
27:             dest = realloc(dest, len_total + 1);
28:             *destptr = *sentence;
29:             destptr++;
30:             sentence++;
31:         }
32: 
33:     }
34:     *destptr = 0;
35:     return dest;
36: }
37: 
38: int main (void)
39: {
40:     char *result;
41: 
42:     result = changewords ("i like it", "i", "ooooooooo");
43:     printf ("%s\n", result);
44:     free (result);
45: }

Valgrind报告:

==20396== Invalid write of size 1
==20396==    at 0x40076F: changewords (changeword4.c:22)
==20396==    by 0x400815: main (changeword4.c:45)
==20396==  Address 0x5204040 is 0 bytes inside a block of size 1 free'd
==20396==    at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20396==    by 0x400766: changewords (changeword4.c:21)
==20396==    by 0x400815: main (changeword4.c:45)
==20396==  Block was alloc'd at
==20396==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20396==    by 0x400701: changewords (changeword4.c:11)
==20396==    by 0x400815: main (changeword4.c:45)
==20396== 
==20396== Invalid read of size 1
==20396==    at 0x4C30C04: strcat (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20396==    by 0x400784: changewords (changeword4.c:23)
==20396==    by 0x400815: main (changeword4.c:45)
==20396==  Address 0x5204040 is 0 bytes inside a block of size 1 free'd
==20396==    at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20396==    by 0x400766: changewords (changeword4.c:21)
==20396==    by 0x400815: main (changeword4.c:45)
==20396==  Block was alloc'd at
==20396==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20396==    by 0x400701: changewords (changeword4.c:11)
==20396==    by 0x400815: main (changeword4.c:45)
==20396== 
==20396== Invalid write of size 1
==20396==    at 0x4C30C30: strcat (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20396==    by 0x400784: changewords (changeword4.c:23)
==20396==    by 0x400815: main (changeword4.c:45)
==20396==  Address 0x5204040 is 0 bytes inside a block of size 1 free'd
==20396==    at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20396==    by 0x400766: changewords (changeword4.c:21)
==20396==    by 0x400815: main (changeword4.c:45)
==20396==  Block was alloc'd at
==20396==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20396==    by 0x400701: changewords (changeword4.c:11)
==20396==    by 0x400815: main (changeword4.c:45)
==20396== 
==20396== Invalid write of size 1
==20396==    at 0x4C30C3F: strcat (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20396==    by 0x400784: changewords (changeword4.c:23)
==20396==    by 0x400815: main (changeword4.c:45)
==20396==  Address 0x5204049 is 8 bytes after a block of size 1 free'd
==20396==    at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20396==    by 0x400766: changewords (changeword4.c:21)
==20396==    by 0x400815: main (changeword4.c:45)
==20396==  Block was alloc'd at
==20396==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20396==    by 0x400701: changewords (changeword4.c:11)
==20396==    by 0x400815: main (changeword4.c:45)
==20396== 
==20396== Invalid write of size 1
==20396==    at 0x4007D2: changewords (changeword4.c:30)
==20396==    by 0x400815: main (changeword4.c:45)
==20396==  Address 0x5204049 is 8 bytes after a block of size 1 free'd
==20396==    at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20396==    by 0x400766: changewords (changeword4.c:21)
==20396==    by 0x400815: main (changeword4.c:45)
==20396==  Block was alloc'd at
==20396==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20396==    by 0x400701: changewords (changeword4.c:11)
==20396==    by 0x400815: main (changeword4.c:45)
==20396== 
==20396== Invalid write of size 1
==20396==    at 0x4007F1: changewords (changeword4.c:36)
==20396==    by 0x400815: main (changeword4.c:45)
==20396==  Address 0x5204061 is 17 bytes after a block of size 16 in arena "client"
==20396== 

==20396== 
==20396== HEAP SUMMARY:
==20396==     in use at exit: 0 bytes in 0 blocks
==20396==   total heap usage: 11 allocs, 11 frees, 1,215 bytes allocated
==20396== 
==20396== All heap blocks were freed -- no leaks are possible
==20396== 
==20396== For counts of detected and suppressed errors, rerun with: -v
==20396== ERROR SUMMARY: 43 errors from 6 contexts (suppressed: 0 from 0)

输出:

ooooooooo loooooooooke ooooooooot

1 个答案:

答案 0 :(得分:2)

char *dest = malloc (len_total + 1);
char *destptr = dest;

好的,destptr指向dest指向的块。

dest = realloc(dest, len_total + 1);
*destptr = *sentence;

当您指向刚刚重新分配的块时,您取消引用destptr。这不可能是正确的。首先交换最后两个语句的顺序。