C瓦尔格林误差

C瓦尔格林误差,c,string,valgrind,allocation,C,String,Valgrind,Allocation,以下代码获取一个输入字符串并将其放在堆上,然后打印它: #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));

以下代码获取一个输入字符串并将其放在堆上,然后打印它:

   #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;
 }
大小为1的无效写入是什么?什么条件跳转或移动取决于未初始化的值

在那一行之后

value[strlen(value)] = input[i];
value
不再是以NUL结尾的字符串,因为您刚刚覆盖了NUL。因此,在下一行中调用
strlen(value)
,并将其用作数组索引将调用UB:

解决方案:

size_t len = strlen(value);
value[len] = input[i];
value[len+1] = '\0';
在那条线之后

value[strlen(value)] = input[i];
value
不再是以NUL结尾的字符串,因为您刚刚覆盖了NUL。因此,在下一行中调用
strlen(value)
,并将其用作数组索引将调用UB:

解决方案:

size_t len = strlen(value);
value[len] = input[i];
value[len+1] = '\0';
问题在于:

value[strlen(value)] = input[i];  
在前一行之后,
value
不再指向以NUL结尾的字符串,因此下一行的
strlen
将返回一个不确定的值:

value[strlen(value) + 1] = '\0';
你需要这个:

...
int len = strlen(value);
value[len] = input[i];
value[len + 1] = '\0';
...
问题在于:

value[strlen(value)] = input[i];  
在前一行之后,
value
不再指向以NUL结尾的字符串,因此下一行的
strlen
将返回一个不确定的值:

value[strlen(value) + 1] = '\0';
你需要这个:

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

该死,我完全忘了这件事。谢谢你,先生!该死,我完全忘了这件事。谢谢你,先生!您可能需要考虑手动跟踪所分配的字符串,而不是使用StrLLN。这也将在一定程度上提高性能。还要注意,调用这样一个循环中的ReLoLc效率非常低,导致堆分割。您可能需要考虑手动跟踪所分配的字符串,而不是使用StrLLN。这也将在一定程度上提高性能。还要注意,在这样的循环中调用realloc效率非常低,并且会导致堆分段。