与 realpath() 缓冲区混淆
Confustion with realpath() buffer
这是我的功能,它在给定目录中查找常规文件,然后将它们的完整路径存储在列表中。
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 的实现(文件只是带有 char *
和指向下一个元素的指针的简单结构):
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]$
是的,空白 space 似乎包含了一些东西(或者这些只是 List_print 中的 '\n'
符号),所以列表不为空。
这里有什么问题?
在 List_push(list, buf);
中,您在列表中存储指向 buf
的指针。你对每个文件都这样做,所以你最终会得到几个指向列表中相同 buf
的指针。打印列表项时,它将显示 buf
.
的(当前)内容
为避免这种情况,您需要创建 buf
的副本并存储它,这样当您为下一个文件重新使用 buf
时,存储的数据不会被覆盖。
这是我的功能,它在给定目录中查找常规文件,然后将它们的完整路径存储在列表中。
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 的实现(文件只是带有 char *
和指向下一个元素的指针的简单结构):
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]$
是的,空白 space 似乎包含了一些东西(或者这些只是 List_print 中的 '\n'
符号),所以列表不为空。
这里有什么问题?
在 List_push(list, buf);
中,您在列表中存储指向 buf
的指针。你对每个文件都这样做,所以你最终会得到几个指向列表中相同 buf
的指针。打印列表项时,它将显示 buf
.
为避免这种情况,您需要创建 buf
的副本并存储它,这样当您为下一个文件重新使用 buf
时,存储的数据不会被覆盖。