I'm encountering a memory leak when I exit my program (found using valgrind) from the tokenize function I've written. Outside of this function, after I assign the tokens to other variables, I call free(tokens) where appropriate, but this doesn't fix the problem. Any help would be hugely appreciated!
Code:
/**
* Splits user input into an array of tokens.
**/
char ** tokenize(const char * s, int * n)
{
/* Sets array of strings and allocates memory, sized appropriately. */
int i;
char * token;
char ** tokens = malloc((BUF_LEN + EXTRA_SPACES) *sizeof(*token));
char buf[BUF_LEN];
strncpy(buf, s, BUF_LEN);
/* Defines first token by a whitespace. */
token = strtok(buf, " ");
i = 0;
/* While loop defines all consequent tokens also with a whitespace. */
while (token)
{
tokens[i] = malloc((strlen(token)+EXTRA_SPACES) *sizeof(*token));
strncpy(tokens[i], token, strlen(token));
i++;
token = strtok(NULL, " ");
}
* n = i;
return tokens;
}
I added a function to free
your array and checked it with valgrind that there is no memory leak.
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <memory.h>
size_t BUF_LEN = 32;
int EXTRA_SPACES = 16;
int length = 0;
char ** tokenize(const char * s, int * n)
{
/* Sets array of strings and allocates memory, sized appropriately. */
int i;
char * token;
char ** tokens = malloc((BUF_LEN + EXTRA_SPACES) *sizeof(*token));
char buf[BUF_LEN];
strncpy(buf, s, BUF_LEN);
/* Defines first token by a whitespace. */
token = strtok(buf, " ");
i = 0;
/* While loop defines all consequent tokens also with a whitespace. */
while (token)
{
tokens[i] = malloc((strlen(token)+EXTRA_SPACES) *sizeof(*token));
strncpy(tokens[i], token, strlen(token));
i++;
token = strtok(NULL, " ");
length++;
}
* n = i;
return tokens;
}
/* deallocates an array of arrays of char*, calling free() on each */
void free_argv(char **argv, unsigned rows) {
for (unsigned row = 0; row < rows; row++) {
free(argv[row]);
}
free(argv);
}
int main ()
{
int i = 12;
char ** ch = tokenize("abc", &i);
free_argv(ch, (unsigned) length);
}
Output
valgrind ./a.out
==28962== Memcheck, a memory error detector
==28962== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==28962== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==28962== Command: ./a.out
==28962==
==28962==
==28962== HEAP SUMMARY:
==28962== in use at exit: 0 bytes in 0 blocks
==28962== total heap usage: 2 allocs, 2 frees, 67 bytes allocated
==28962==
==28962== All heap blocks were freed -- no leaks are possible
==28962==
==28962== For counts of detected and suppressed errors, rerun with: -v
==28962== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)