Valgrind gives me the following error in the below code: Invalid write of size 8 : Address XX is 32 bytes inside a block of size 33 alloc'd
/*The function allocate memory and clean it for further use.*/
static void *ft_mal(size_t size)
{
void *ret;
char *tmp;
ret = malloc(size); /*LINE WITH ERROR*/
if (!ret)
return (NULL);
tmp = ret;
while (size) {
*tmp = 0;
tmp++;
size--;
}
return (ret);
}
I use this function in the below code where I also have two Invalid write of size 8 error on commented lines:
/*Splits a string into an array of strings*/
char **ft_splt(const char *s, char c)
{
char **ret;
char *str;
int i;
i = ct_wd(s, c);
ret = (char **)ft_mal(sizeof(*ret) * i + 1);
str = (char *)ft_mal(sizeof(*str) * ct_c(s, c) + i);
i = 0;
while (*s) {
while (*s && *s == c)
s++;
ret[i++] = (*s ? str : '\0'); /*LINE WITH ERROR*/
while (*s && *s != c)
*str++ = *s++;
if (*s)
*str++ = '\0';
}
ret[i] = 0; /*LINE WITH ERROR*/
return (ret);
}
I don't get why it produces the errors and therefore don't know how to solve them either. Consequently I have an error when I free the mallocs.
How do I have to do to solve these invalid read / write errors ?
Edit:
As required I give a little more code. ct_wd and ct_c respectively count the number of words and the number of characters in the string arguments in order to create the right sized malloc.
static int ct_wd(const char *s, char c)
{
int nb;
nb = 0;
while (*s) {
while (*s && *s == c)
s++;
while (*s && *s != c)
s++;
nb = (*(s - 1) != c ? nb + 1 : nb);
}
return (nb);
}
static int ct_c(const char *s, char c)
{
int nb;
nb = 0;
while (*s) {
if (*s != c)
nb++;
s++;
}
return (nb);
}
Here is a main.c example:
int main()
{
char s[] = "lut:les:enf:? ";
char **ret;
int i = 0;
ret = ft_splt(s, ':');
while (ret[i]) {
printf("[Resultat :]\n");
i++;
}
/* free all malloced pointer */
return (0);
}
Edit: SOLUTION
As mentionned below there was a mistake:
ret = (char **)ft_mal(sizeof(*ret) * i + 1);
should instead be:
ret = (char **)ft_mal(sizeof(*ret) * (i + 1));
I still had a seg fault on execution. Seems like removing this line :
ret[i] = 0;
removed both the valgrind error and the segfault. I understand this line was not really necessary as ft_mal already cleaned the memory, still I don't really get why this both produced a write error in valgrind and made me seg fault.
ct_wd
andct_c
do? If you could provide something with a dummy implementation of them and amain()
function, this would be far easier to debug. – ablighmalloc()
somehow? – wallykft_mal()
is an implementation ofmalloc() + memset()
. – alvits