Home > Net >  C - Getting bus error when passing directly string in param
C - Getting bus error when passing directly string in param

Time:09-12

Making my own version of strtrim in C and its working fine but I wonder why it's working if I declare 2 array of char, like this:

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("%s\n", s);
    free(s);
    return (0);
}

But not if I pass directly a string directly in param. I'm getting bus error if I do this

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

I must have missed something in my training ^^
Thank's in advance !
EDIT:
Thank's for reply !
Thank you for your advice, I took care to write them down, I thank you again, and I also found out why it wasn't working, it's because I'm trying to close the string and as you told me: it's a read-only string;

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));
}

CodePudding user response:

At least this statement does not make a sense

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

because there can be passed a negative value s1 - s that will be converted to a very big positive value in the function ft_strsub because the corresponding parameter has an unsigned integer type.

Pay attention to that the compiler can issue a message that you are discarding the qualifier const as for example

char    *s;

s = (char *)s1;

Also the function can return a pointer that does not point to a dynamically allocated array that you are tries to free with the function free

if (!*s)
    return (s);

//...

free(s);

CodePudding user response:

Here's a few lines of code you might consider to replace your is_set() function:

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

Don't "cast away" const-ness unnecessarily. Exploit the "conditional" segment of the for() loop. Return is also a conditional: "If not reaching the end of the string of 'bad' characters, then 'c' was 'matched' in that string.

If you get "trimming the front" working, perhaps a simple "reverse string" can be used to "trim the back end, too", then "reverse string" once more. Re-use code that works.

Seeing this function, it can be made even simpler:

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

Often the best solution is to use fewer resources (like variables) but to use them wisely. Then, flaws have fewer places to hide.

  •  Tags:  
  • c
  • Related