C - 在参数中直接传递字符串时出现总线错误

  • 本文关键字:字符串 错误 总线 参数 c
  • 更新时间 :
  • 英文 :


在C 中制作我自己的 strtrim 版本并且工作正常,但我想知道如果我声明 2 个字符数组,为什么它会工作,如下所示:

static int  is_set(const char *set, char c)
{
char    *s;
s = (char *)set;
while (*s)
{
if (*s == c)
return (1);
s++;
}
return (0);
}
static char *ft_strsub(char const *str, unsigned int start, unsigned int end)
{
char        *res;
char        *s;
size_t      size;
int         i;
size = end - start;
res = malloc(size + 1);
if (!res)
return (res);
s = (char *)str + start;
i = 0;
while (*s && end-- > start)
res[i++] = *s++;
res[i] = 0;
return (res);
}
char    *ft_strtrim(char const *s1, char const *set)
{
char    *start;
char    *s;
s = (char *)s1;
while (*s && is_set(set, *s))
s++;
if (!*s)
return (s);
start = s;
while (*s)
s++;
while (is_set(set, *--s))
;
if (*s)
*++s = 0;
return (ft_strsub(start, 0, s1 - s));
}
int main(void)
{
char tst[] = "   xxxtripouille";
char tst2[] = " x";
char * s = ft_strtrim(tst, tst2);
printf("%sn", s);
free(s);
return (0);
}

但是如果我直接在参数中直接传递字符串,则不会。如果我这样做,我会收到总线错误

int main(void)
{
/*char tst[] = "   xxxtripouille";
char tst2[] = " x";*/
char * s = ft_strtrim("   xxxtripouille", " x");
printf("%sn", s);
free(s);
return (0);
}

我一定在训练中错过了什么^^
提前谢谢!
编辑:
谢谢你的回复!
谢谢你的建议,我小心翼翼地把它们写下来,我再次感谢你,我也发现了为什么它不起作用,这是因为我试图关闭字符串,正如你告诉我的那样:它是一个只读字符串;

char    *ft_strtrim(char const *s1, char const *set)
{
char    *start;
char    *s;
s = (char *)s1;
while (*s && is_set(set, *s))
s++;
if (!*s)
return (ft_strdup(s));
start = s;
while (*s)
s++;
while (is_set(set, *--s))
;
if (*s)
++s;
return (ft_strsub(start, 0, s - start));
}

以下是您可以考虑替换is_set()函数的几行代码:

static int matchAny( const char *set, char c ) {
const char *s = set;
for( ; *s && *s != c; s++ )
; // just searching
return *s != ''; // true = match found
}

不要不必要地"抛弃"恒心。利用for()循环的"条件"段。返回也是一个条件:"如果没有到达'坏'字符字符串的末尾,那么'c'在该字符串中被'匹配'。

如果你让"修剪前端"工作,也许可以使用一个简单的"反向字符串"来"修剪后端",然后再次"反向字符串"。重用有效的代码。

看到这个功能,可以做得更简单:

static int matchAny( const char *set, const char c ) {
while( *set && *set != c )
set++; // just searching
return *set != ''; // true = match found
}

通常,最好的解决方案是使用更少的资源(如变量),但要明智地使用它们。然后,缺陷的隐藏位置就更少了。

至少这种说法没有意义

return (ft_strsub(start, 0, s1 - s));

因为可以传递一个负值s1 - s,该负值将在函数ft_strsub中转换为非常大的正值,因为相应的参数具有无符号整数类型。

请注意,编译器可以发出一条消息,指出您正在丢弃限定符 const,例如

char    *s;
s = (char *)s1;

此外,该函数可以返回一个指针,该指针不指向您尝试使用函数释放的动态分配数组

free
if (!*s)
return (s);
//...
free(s);

最新更新