与realpath()缓冲区混淆

时间:2015-02-22 14:14:17

标签: c linked-list memset realpath

这是我的功能,它在给定目录中查找常规文件,然后在列表中存储它们的完整路径。

static my_func(const char *path, Files **list) //list - storage for file names
{
    DIR *d;
    struct dirent *dir;
    char buf[PATH_MAX + 1];

    d = opendir(path);
    if (d) {
        while ((dir = readdir(d)) != NULL) {
            if ((DT_REG == dir->d_type)) {

                realpath(dir->d_name, buf);
                List_push(list, buf);
                printf("%s\n", dir->d_name);
                // memset(buf, 0, PATH_MAX + 1);
            }
        }
    }
    closedir(d);
    return 0;
}
...
...

int main()
{
    // list creation
    // my_func call
    ...
    List_print(...)
}

预期产出:

FILE_1.txt
FILE_2.txt
FILE_3.txt
FILE_4.txt
FILE_5.txt
/home/user/c/FILE_1.txt
/home/user/c/FILE_2.txt
/home/user/c/FILE_3.txt
/home/user/c/FILE_4.txt
/home/user/c/FILE_5.txt

当前输出:

FILE_1.txt
FILE_2.txt
FILE_3.txt
FILE_4.txt
FILE_5.txt
/home/user/c/FILE_1.txt
/home/user/c/FILE_1.txt
/home/user/c/FILE_1.txt
/home/user/c/FILE_1.txt
/home/user/c/FILE_1.txt

它可以与我的链表实现相关吗?它运行正常,因为我测试了它:

List_push(list, dir->d_name)

并获得了预期的结果。这是List_push的实现(Files只是带有char *的struct和指向下一个元素的指针):

void List_push(Files **head, char *x)
{
    Files *new;

    new   = malloc(sizeof(Files));

    if (NULL != new) {
        new->next = *head;
        new->text = x;
        *head = new;
    } else {
        printf("malloc error");
    }

}

另外,正如您所看到的,我试图用memset清除buf,但没有成功 - 输出为:

FILE_1.txt
FILE_2.txt
FILE_3.txt
FILE_4.txt
FILE_5.txt






[console]$

是的,空格似乎存在某些内容(或者这些只是List_print中的'\n'个符号),因此列表不为空。

这里有什么问题?

1 个答案:

答案 0 :(得分:2)

List_push(list, buf);中,您将指向buf的指针存储在列表中。您为每个文件执行此操作,因此您最终会在列表中找到指向同一buf的指针。打印列表项时,它将显示buf的(当前)内容。

为避免这种情况,您需要创建buf的副本并存储该副本,以便在您为下一个文件重用buf时不会覆盖存储的数据。