我找不到heisenbug

时间:2018-07-24 04:23:12

标签: c segmentation-fault heisenbug

我一直在研究名为ft_split_whitespaces的c程序。

该程序应该做的是找到单词并将它们放入字符串数组。

我必须对一个项目执行此操作,并且除malloc()sizeof()之外,不能使用任何其他功能。我仅将printf()和其他东西用于调试目的。

所以,我遇到了一个问题,当我调试程序时它可以正常运行,如果我运行它,则会出现段错误。

我研究了这个话题,结果证明这是一个海森堡。我尝试了几种通过关闭调试器优化来发现bug的方法,但是结果始终是,如果我逐步检查程序,它会起作用,否则,它将不会。

我遇到的另一个奇怪的事情是,该程序可以在我的计算机上正常运行,但是当在另一台计算机上运行时,它将再次出现段错误。

这是我的程序,任何帮助都会很棒。

#include <stdlib.h>
#include <stdio.h>
#define W1(c)   (c == ' ' ||  c == '\n' || c == '\t')
#define W2(c)   (c == '\v' || c == '\f' || c == '\r')

int     ft_wordcount(char *str)
{
    int i;
    int ws;

    ws = 1;
    i = 0;
    while (*str)
    {
        if (W1(*str) || W2(*str))
            ws = 1;
        else
        {
            if (ws)
                i++;
            ws = 0;
        }
        str++;
    }
    return (i);
}

int     ft_wordlen(char *str)
{
    int ln;

    ln = 0;
    while (!(W1(*str)) && !(W2(*str)) && *str != '\0')
    {
        ln++;
        str++;
    }
    return (ln);
}

char    **ft_assign(char *str)
{
    int     i;
    char    **res;
    int wordcount;
    int ln;

    i = 0;
    wordcount = ft_wordcount(str);
    res = (char **)malloc(wordcount * sizeof(char));
    while (i < wordcount)
    {
        if (!(W1(*str)) && !(W2(*str)))
        {
            ln = ft_wordlen(str);
            res[i] = malloc((ln + 1) * sizeof(char));
            res[i][ln] = '\0';
            str += ln;
            i++;
        }
        str++;
    }
    return (res);
}

char **ft_split_whitespaces(char *str)
{
    char    **res;
    int     i;
    int     wordcount;
    int     pos;

    wordcount = ft_wordcount(str);
    i = 0;
    res = ft_assign(str);
    while (i < wordcount)
    {
        if (!(W1(*str)) && !(W2(*str)))
        {
            pos = 0;
            while (!(W1(*str)) && !(W2(*str)) && *str != '\0')
                res[i][pos++] = *(str++);
            i++;
        }
        str++;
    }
    return (res);
}


int main(void)
{
    int i;
    int ln;
    i = 0;
    char test[] = "yes  no yuuh     WORD   adjdsfjlksdj   sdfjkdsfjkjsd     sfdkjsdlkjf  sfdds\tfsd";
    char **words;
    words = ft_split_whitespaces(test);
    ln = ft_wordcount(test);
    while (i < ln)
    {
        printf("%s\n", words[i]);
        i++;
    }
}

2 个答案:

答案 0 :(得分:2)

您的代码中存在多个问题:

  • W1W2中的参数在扩展中未正确括上括号。您至少应该这样写:

    #define W1(c)   ((c) == ' '  || (c) == '\n' || (c) == '\t')
    #define W2(c)   ((c) == '\v' || (c) == '\f' || (c) == '\r')
    

    但是c仍将被乘以评估,因此副作用将发生多次。请勿为此使用宏,而应使用内联函数:

    static inline int W1(int c) { return (c == ' '  ||  c == '\n' || c == '\t'); }
    static inline int W2(int c) { return (c == '\v' || c == '\f' || c == '\r'); }
    
  • ft_assign中的分配大小不正确:res = (char **)malloc(wordcount * sizeof(char));应该写为:

    res = malloc(wordcount * sizeof(char *));
    

    或更好:

    res = malloc(wordcount * sizeof(*res));
    
  • 您忘记将字符串复制到分配的块中:res[i][ln] = '\0';之前应加上:

    memcpy(res[i], str, ln);
    

    或者如果您的系统上有strndup,只需将其替换为

    res[i] = strndup(str, ln);
    

答案 1 :(得分:1)

您的代码的主要问题是res中的ft_assign分配:

res = (char **)malloc(wordcount * sizeof(char));

应该是:

res = (char **)malloc(wordcount * sizeof(char*));

或更佳:

res = malloc(wordcount * sizeof *res);

实际上,sizeof(char)是一个,sizeof(char*)是4(在32位cpu上)或8(在64bits上),因此,由于缺少此简单的*,分配的内存太少了。 / p>


另请参阅:why you should not cast malloc result