segfault when referenced by index

Viewed 93

The convert_list_toarr function takes a linked list as an argument. Next, it convert the linked list into array. Next, using print_matrix, I want to print the array to the console.

I get a segfault in print_matrix. When accessing the element arr[1][0] of the array.

My code

char        **convert_list_toarr(t_list **map_list)
{
    int     size;
    char    **arr;
    t_list  *tmp;
    int     i;

    i = 0;
    tmp = *map_list;
    size = ft_list_size(*map_list);
    arr = (char **)malloc(sizeof(char *) * size);
    while (tmp->next != NULL)
    {
        arr[i] = ft_strdup((char *)tmp->content);
        tmp = tmp->next;
    }
    ft_list_clear(map_list);
    print_matrix(arr, size);
    return (arr);
}

My print_matrix

void        print_matrix(char **map, int size)
{
    int i;
    int j;

    i = 0;
    while (i < size)
    {
        j = 0;
        while (map[i][j] != '\0')
        {
            write(1, &map[i][j], 1);
            j++;
        }
        i++;
    }
}

My ft_strdup

/*
** Function:        char *ft_strdup
**
** Description:     The ft_strdup() function allocates sufficient memory for a
** copy of thestring s1, does the copy, and returns a pointer to it.
** The pointer may subsequently be used as an argument to the function free(3).
*/

char    *ft_strdup(const char *s)
{
    char    *dest;
    int     i;
    int     n;

    i = 0;
    n = ft_strlen(s);
    if (!(dest = (char *)malloc((n * sizeof(char)) + 1)))
        return (NULL);
    while (i < n)
    {
        dest[i] = s[i];
        i++;
    }
    dest[n] = '\0';
    return (dest);
}

My console output 1111111111[1] 11491 segmentation fault

2 Answers

There are two problems with this while loop

while (tmp->next != NULL)
{
    arr[i] = ft_strdup((char *)tmp->content);
    tmp = tmp->next;
}

The first one is that you have to check whether tmp is equal to NULL.

while (tmp != NULL)
{
    //...
} 

The second one is that you forgot to increment the variable i.

while (tmp != NULL)
{
    arr[i++] = ft_strdup((char *)tmp->content);
    tmp = tmp->next;
}

Instead of while (tmp->next != NULL) you should have:

while (tmp != NULL)

All of the while loops would be much safer and more readable converted as for loops:

char **convert_list_toarr(t_list **map_list) {
    int     size;
    char    **arr;
    t_list  *tmp;
    int     i;

    size = ft_list_size(*map_list);
    arr = malloc(sizeof(*arr) * size);
    if (arr != NULL) {
        for (tmp = *map_list, i = 0; tmp != NULL; tmp = tmp->next, i++) {
            arr[i] = ft_strdup((char *)tmp->content);
        }
        ft_list_clear(map_list);
        print_matrix(arr, size);
    }
    return arr;
}
Related