Search code examples
clinked-listopendir

Trying to store file/folder names from dirent struct to linked list


typedef struct s_files
{
    char *name;
    struct s_files *next;
} t_files;

t_files *add_files()
{
    DIR *pDir;
    struct dirent *pDirent;

    t_files *head = (t_files *)malloc(sizeof(t_files));
    t_files *cur = head;

    pDir = opendir(".");
    while((pDirent = readdir(pDir)))
    {
        if(cur == NULL)
            cur = (t_files *)malloc(sizeof(t_files));
        cur->name = pDirent->d_name;
        cur->next = NULL;
        cur = cur->next;
    }
    closedir(pDir);
    return (head);
}



void print_files(t_files *head)
{
    for ( ; head != NULL; head = head->next )
        printf( "%s ", head->name);
}

I am trying to store filenames from dirent struct to linked list. But when I tried to print all, only first one gets outputted.

Output should be similar to "ls -a"


Solution

  • Try:

    t_files *add_files()
    {
        DIR *pDir;
        struct dirent *pDirent;
    
        t_files *head;
        t_files *cur = NULL;
    
        pDir = opendir(".");
        while((pDirent = readdir(pDir)))
        {
            if (cur == NULL)
            {
                cur = (t_files *)malloc(sizeof(t_files));
                head = cur;
            }
            else
            {
                cur->next = (t_files *)malloc(sizeof(t_files));
                cur = cur->next;
            }
            cur->name = strdup(pDirent->d_name);
        }
        cur->next = NULL;
    
        closedir(pDir);
        return (head);
    }
    
    • First you have directly overwritten the first node, resulting in a memory leak.
    • Then you have incremented cur to the next node, but then you loose your pointer to the last node, so you haven't assigned the next node to your last node. This results in a memory leak and also you aren't saving any information besides the first node.
    • I think you don't own pDirent, so you should take a copy of the name. Make sure to free it.

    Note, that this code, like yours, doesn't check for malloc or strdup returning NULL, which you should always do.

    See: Should I cast the result of malloc? for why you maybe shouldn't cast the result of malloc.

    Also always consider enclosing an if into a block. There have been serious bugs due to this.