Valgrind错误:malloc时读/写无效

Valgrind错误:malloc时读/写无效,c,malloc,valgrind,free,C,Malloc,Valgrind,Free,Valgrind在以下代码中给出了以下错误: 大小为8的写入无效:地址XX是大小为33 alloc'd的块中的32字节 /*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 (!re

Valgrind在以下代码中给出了以下错误: 大小为8的写入无效:地址XX是大小为33 alloc'd的块中的32字节

/*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);
}
我在下面的代码中使用此函数,在注释行中还有两个大小为8的无效写入错误:

/*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);
}
我不明白它为什么会产生错误,因此也不知道如何解决它们。因此,我在释放mallocs时出错

如何解决这些无效的读/写错误

编辑:

根据需要,我给出了更多的代码。 ct_wd和ct_c分别计算字符串参数中的字数和字符数,以创建适当大小的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);
}
下面是一个main.c示例:

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);
}
编辑:解决方案

如下文所述,存在一个错误:

ret = (char **)ft_mal(sizeof(*ret) * i + 1);
应改为:

ret = (char **)ft_mal(sizeof(*ret) * (i + 1));
我在执行死刑时仍然犯了seg错误。似乎要删除此行:

ret[i] = 0;
消除了valgrind错误和SEG故障。 我知道这一行并不是真的必要,因为ft_-mal已经清除了内存,但我仍然不明白为什么这两种情况都会在valgrind中产生写入错误,并导致我出现seg故障。

反向工作:

最后的错误很容易。我认为您打算将
ret
作为以零结尾的
char*
数组。但你是这样分配的:

ret = (char **)ft_mal(sizeof(*ret) * i + 1);
如果要为终止的
null
多输入一个条目,则需要
i+1
大小为
*ret
的条目,即

ret = (char **)ft_mal(sizeof(*ret) * (i + 1));
前面的错误更难。这一行:

ret[i++] = (*s ? str : '\0'); /*LINE WITH ERROR*/
ret = malloc(size); /*LINE WITH ERROR*/
这令人困惑
ret[i++]
似乎是一个
char*
。但您似乎正在复制
字符
。你想在这里干什么?使用
-Wall
编译时会发生什么?我打赌你看到了警告

这一行:

ret[i++] = (*s ? str : '\0'); /*LINE WITH ERROR*/
ret = malloc(size); /*LINE WITH ERROR*/
看起来不太可能产生您建议的valgrind错误。我建议使用
-O0-g-Wall
编译,并在修复其他位后重试,然后仔细检查行号


它产生了
free()
错误,因为你从来没有
free()
任何东西。

如果你希望有人帮助你调试它,就发布一条消息。在计算要分配的内存量的例程中,很可能出现了一个逐个错误。特别是
ct\u wd
ct\u c
应该做什么?如果你能提供一个虚拟的实现和一个
main()
函数,那么调试起来就容易多了。你有没有可能以某种方式重新定义了
malloc()
?看起来
ft\u mal()
malloc()+memset()
的一个实现。是的,这就是它。我的代码是一个学校项目的一部分,该项目禁止使用上述命名函数。我感谢您的帮助。我把“I+1”改成了一个明显的“(I+1)”曾经说过。。。I malloc的大小等于句子中的字符数+字数x字符大小(\0)。然后复制大malloc中的单词减去拆分字符,并在每个单词的末尾添加一个\0。行“ret[i++]=(*s?str:'\0');”使ret数组的每个单元格指向句子的开头。