Valgrind 大小为 1 的无效写入和读取以及字节丢失

Valgrind Invalid write and read of size 1 and bytes lost

我正在做一个带有内存分配的拆分函数。我 运行 它通过 valgrind 并出现了一堆泄漏和丢失的字节。

这是我的函数:

char **split(const char *str, char delim, int *n) {
  int count = 1;
  int len = strlen(str);
  char **words;
  for (int i = 0; i < len; i++) {
    if (str[i] == delim || str[i] == '\n' || str[i] == '[=10=]')
      count++;
  }
  *n = count;
  words = (char **)malloc(count * sizeof *words);
  char arr[100];
  int j = 0, indeks = 0;
  for (int i = 0; i < len + 1; i++) {
    if (str[i] != delim && str[i] != '\n' && str[i] != '[=10=]') {
      arr[j++] = str[i];
    } else {
      arr[j] = '[=10=]';
      j = 0;
      words[indeks] = malloc(strlen(arr) * sizeof *words);
      words[indeks] = strcpy(words[indeks], arr);
      indeks++;
    }
  }

  words[indeks] = malloc(sizeof *words[indeks]);
  words[indeks][0] = '[=10=]';
  return words;
} 

这是我的主要内容:

int main() {
  int n = 0;
  char *str = "hello world !!!";
  char delim = ' ';
  printf("Input string: %s\n", str);
  printf("delimiter: %c\n", delim);

  char **words = split(str, delim, &n);
  printf("words:\n");
  for (int i = 0; i < n; i += 1) {
    printf("%s\n", words[i]);
  }
  free(words);
}

内存泄漏:

==12853== Invalid write of size 1
==12853==    at 0x4C34EAB: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12853==    by 0x108A49: split (naloga_3.h:28)
==12853==    by 0x108B4E: main (main.c:10)
==12853==  Address 0x52302f0 is 0 bytes after a block of size 0 alloc'd
==12853==    at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12853==    by 0x1089FE: split (naloga_3.h:27)
==12853==    by 0x108B4E: main (main.c:10)
==12853== 
==12853== Invalid write of size 8
==12853==    at 0x108A95: split (naloga_3.h:33)
==12853==    by 0x108B4E: main (main.c:10)
==12853==  Address 0x52300a8 is 0 bytes after a block of size 40 alloc'd
==12853==    at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12853==    by 0x108906: split (naloga_3.h:18)
==12853==    by 0x108B4E: main (main.c:10)
==12853== 
==12853== Invalid read of size 8
==12853==    at 0x108AB2: split (naloga_3.h:34)
==12853==    by 0x108B4E: main (main.c:10)
==12853==  Address 0x52300a8 is 0 bytes after a block of size 40 alloc'd
==12853==    at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12853==    by 0x108906: split (naloga_3.h:18)
==12853==    by 0x108B4E: main (main.c:10)
==12853== 
==12853== Invalid read of size 1
==12853==    at 0x4C34D32: __strlen_sse2 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12853==    by 0x4EBE981: puts (ioputs.c:35)
==12853==    by 0x108B86: main (main.c:13)
==12853==  Address 0x52302f0 is 0 bytes after a block of size 0 alloc'd
==12853==    at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12853==    by 0x1089FE: split (naloga_3.h:27)
==12853==    by 0x108B4E: main (main.c:10)
==12853== 
==12853== 1 bytes in 1 blocks are definitely lost in loss record 1 of 2
==12853==    at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12853==    by 0x108A94: split (naloga_3.h:33)
==12853==    by 0x108B4E: main (main.c:10)
==12853== 
==12853== 232 bytes in 5 blocks are definitely lost in loss record 2 of 2
==12853==    at 0x4C31B0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12853==    by 0x1089FE: split (naloga_3.h:27)
==12853==    by 0x108B4E: main (main.c:10)
==12853== 

谁能帮我调用 malloc 函数。

函数错误。例如在这个声明中

words[indeks] = malloc(strlen(arr) * sizeof *words);

您分配的是指针数组而不是字符数组。你需要写

words[indeks] = malloc(strlen(arr) + 1 );

这个作业

words[indeks] = strcpy(words[indeks], arr);

没有多大意义。写

就够了
strcpy(words[indeks], arr);

并且您还需要释放所有已分配的存储字符串的数组。

请注意,当源字符串包含相邻空格时,该函数将无法正常工作。

我建议让您的代码更简单,并使用 strdup 而不是 mallocstrcpystrdup 将负责分配正确数量的内存和空终止结果字符串。

修复无效内存访问后,您可以查看泄漏。