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.