我一直在研究名为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++;
}
}
答案 0 :(得分:2)
您的代码中存在多个问题:
宏W1
和W2
中的参数在扩展中未正确括上括号。您至少应该这样写:
#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>