How to solve invalid read in C

274 views Asked by At

I'm having an invalid read issue with my program, I'm creating a simple shell in c which support history and it's built-ins. Here's my problem I have a variable

 char *cmd = malloc(sizeof(char) * 256);

Wen I run the command ^p^l^, now cmd = ^p^l^, I pass cmd to a search function that searches through history and return a match or the same string. ft_man_search_replace(&cmd, &pos, hist)

void    ft_man_search_replace(char **cmd, int *pos, t_stack hist)
{
    char            **split;
    t_search_hist   search;
    int             i;

    // splits ^string^string^ into array
    split = ft_strsplit(*cmd + 1, '^');
    i = *pos;
    // get previous history and assign it to haystack
    search.haystack = ft_get_prev_hist(hist);
    search.needle = split[0];
    search.with = split[1];
    *cmd = ft_search_replace(search, 0, 0, 0);
     //if returned string is equal to *cmd, there was no match
     //assign *cmd to empty string.
    if (ft_strequ(search.haystack, *cmd))
    {
        ft_putendl("\n21sh: substitution failed");
        *cmd = "";
        *pos = 0;
        return ;
    }
    i = ft_strlen(*cmd);
    ft_cursor(*cmd, i + 1, &hist);
    *pos = i;
}

After running this function it's seems that cmd is no longer having memory allocation of 256, when I type something I get invalid read my guess is that I'm reaching the end of the string. e.g if the match was not found I assign *cmd = "", now if I try to modify cmd I get invalid read. How can I solve this? I tried reallocating using the below function, as I'm not allowed to use realloc.

void    *ft_realloc(void *ptr, size_t len)
{
    void    *real;

    real = (void *)malloc(len);
    if (real)
    {
        memset(real, 0, len);
        memcpy(real, ptr, strlen(ptr));
    }
    free(ptr);
    return (real);
}
1

There are 1 answers

0
Junius L On

Ok, I have managed to solve the issue, as user3121023 pointed out that *cmd = will discard the memory allocation, I decided to use strcpy and memset instead of =.

//libraries here
# define SIZE 256   

char *cmd = malloc(sizeof(char) * SIZE);

void    ft_man_search_replace(char **cmd, int *pos, t_stack hist)
{
    char            **split;
    t_search_hist   search;
    int             i;

    // splits ^string^string^ into array
    split = ft_strsplit(*cmd + 1, '^');
    i = *pos;
    // get previous history and assign it to haystack
    search.haystack = ft_get_prev_hist(hist);
    search.needle = split[0];
    search.with = split[1];
    memset(*cmd, 0, SIZE);
    strcpy(*cmd, ft_search_replace(search, 0, 0, 0));
     //if returned string is equal to *cmd, there was no match
     //assign *cmd to empty string.
    if (ft_strequ(search.haystack, *cmd))
    {
        ft_putendl("\n21sh: substitution failed");
        memset(*cmd, 0, SIZE);
        strcpy(*cmd, "");
        *pos = 0;
        return ;
    }
    i = ft_strlen(*cmd);
    ft_cursor(*cmd, i + 1, &hist);
    *pos = i;
}