简体   繁体   English

C valgrind错误

[英]C valgrind errors

The following code takes an input string and puts it on the heap, then prints it: 以下代码接受一个输入字符串,并将其放在堆上,然后打印出来:

   #include <stdio.h>
   #include <stdlib.h>
   #include <string.h>

   int main() {

      char input[50] = "BLA BLBA BLA BLA DJAIO JASJDIOA";
      char *value = (char*) calloc(1, sizeof(char));

      value[0] = '\0';


      for (int i = 0; i < strlen(input); i++) {

          value = (char*) realloc(value, sizeof(char) * (strlen(value) + 2));
          if (value == NULL)
              return 1;

          value[strlen(value)] = input[i];
          value[strlen(value) + 1] = '\0';
      }

      printf("%s\n", value);

      free(value);
      return 0;
 }

Works perfectly, but from some reason it gives these errors from valgrind: 完美地工作,但是由于某种原因,它给出了valgrind的这些错误:

 ==109423== Memcheck, a memory error detector ==109423== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. ==109423== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info ==109423== Command: ./write_test.o ==109423== ==109423== Conditional jump or move depends on uninitialised value(s) ==109423== at 0x4C2A9E8: strlen (vg_replace_strmem.c:454) ==109423== by 0x400722: main (in /home/me/testing/write_test.o) ==109423== ==109423== Invalid write of size 1 ==109423== at 0x40072E: main (in /home/me/testing/write_test.o) ==109423== Address 0x51f4092 is 0 bytes after a block of size 2 alloc'd ==109423== at 0x4C29B78: realloc (vg_replace_malloc.c:785) ==109423== by 0x4006E5: main (in /home/me/testing/write_test.o) ==109423== ==109423== Conditional jump or move depends on uninitialised value(s) ==109423== at 0x4C2A9E8: strlen (vg_replace_strmem.c:454) ==109423== by 0x4006D2: main (in /home/me/testing/write_test.o) ==109423== ==109423== Conditional jump or move depends on uninitialised value(s) ==109423== at 0x4C2A9E8: strlen (vg_replace_strmem.c:454) ==109423== by 0x400703: main (in /home/me/testing/write_test.o) ==109423== ==109423== Conditional jump or move depends on uninitialised value(s) ==109423== at 0x4C2AA08: __GI_strlen (vg_replace_strmem.c:455) ==109423== by 0x4E9FEEB: puts (ioputs.c:36) ==109423== by 0x40075B: main (in /home/me/testing/write_test.o) ==109423== ==109423== ==109423== HEAP SUMMARY: ==109423== in use at exit: 0 bytes in 0 blocks ==109423== total heap usage: 32 allocs, 32 frees, 528 bytes allocated ==109423== ==109423== All heap blocks were freed -- no leaks are possible ==109423== ==109423== For counts of detected and suppressed errors, rerun with: -v ==109423== Use --track-origins=yes to see where uninitialised values come from ==109423== ERROR SUMMARY: 123 errors from 5 contexts (suppressed: 0 from 0) 

What invalid write of size 1? 大小为1的无效写入是什么? What Conditional jump or move depends on uninitialised value? 哪些条件跳转或移动取决于未初始化的值?

After that line 在那条线之后

value[strlen(value)] = input[i];

value is no longer a NUL terminated string because you have just overwritten NUL. value不再是NUL终止的字符串,因为您刚刚覆盖了NUL。 So calling strlen(value) in the next line and using it as array index invokes UB: 因此,在下一行中调用strlen(value)并将其用作数组索引将调用UB:

Solution: 解:

size_t len = strlen(value);
value[len] = input[i];
value[len+1] = '\0';

The problem is here: 问题在这里:

value[strlen(value)] = input[i];  

after the previous line, value doesn't point anymore to a NUL terminated string, therefore the strlen on the following line will return an indeterminate value: 在上一行之后, value不再指向以NUL终止的字符串,因此,在下一行上的strlen将返回不确定的值:

value[strlen(value) + 1] = '\0';

You need this: 你需要这个:

...
int len = strlen(value);
value[len] = input[i];
value[len + 1] = '\0';
...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM