Home > Back-end >  Valgrind Invalid write and read of size 1 and bytes lost
Valgrind Invalid write and read of size 1 and bytes lost

Time:05-30

I was doing a split function with memory allocation. And I ran it through valgrind and came to a bunch of leaks and lost bytes.

Here's my function:

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] == '\0')
      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] != '\0') {
      arr[j  ] = str[i];
    } else {
      arr[j] = '\0';
      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] = '\0';
  return words;
} 

Here's my main:

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);
}

Memory leaks:

==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== 

Can someone help me with the malloc function calls.

CodePudding user response:

The function is wrong. For example in this statement

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

you are allocating an array of pointers instead of an array of characters. You need to write

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

This assignment

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

does not make a great sense. It is enough to write

strcpy(words[indeks], arr);

And you need also to free all allocated arrays that store strings.

Pay attention to that the function will not correctly work when the source string contains adjacent spaces.

  • Related