You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

生成文件名链表字符串时缺失第二个节点,求排查原因

问题根源分析与解决方案

我一眼就看出问题出在file_node_init的实现上——你大概率没有复制dir->d_name的字符串内容,只是直接保存了指针!这是使用readdir时非常容易踩的坑。

为什么会出现节点丢失/为空的情况?

readdir返回的struct dirent里的d_name是指向内部复用缓冲区的,每次调用readdir,这个缓冲区都会被新的目录项内容覆盖。如果你的file_node_init只是把dir->d_name的指针直接赋值给file_node->filename,那么链表中所有节点的filename都会指向同一块内存:

  • 当你在get_file_list刚生成链表后调用file_list_print,缓冲区的内容刚好对应当前遍历到的节点,所以看起来是完整的;
  • 但当你后续调用file_list_tostring时,readdir的缓冲区已经被多次覆盖,甚至在某些循环周期内缓冲区内容为空,就会出现你看到的tmp为空、节点缺失的情况。

验证你的file_node_init(大概率是这样的错误实现)

如果你的file_node_init是类似下面的代码,那完全符合上述问题:

struct file_node *file_node_init(char *name) {
    struct file_node *node = malloc(sizeof(struct file_node));
    node->filename = name; // 直接存指针,没有复制字符串!
    node->prev = node->next = NULL;
    return node;
}

修复方案:复制字符串到独立内存

修改file_node_init,为每个节点的filename分配独立内存并复制字符串内容,避免依赖readdir的复用缓冲区:

struct file_node *file_node_init(const char *name) {
    struct file_node *node = malloc(sizeof(struct file_node));
    if (!node) {
        perror("malloc");
        return NULL;
    }
    // 为文件名分配独立内存并复制内容
    node->filename = malloc(strlen(name) + 1);
    if (!node->filename) {
        perror("malloc");
        free(node); // 避免内存泄漏
        return NULL;
    }
    strcpy(node->filename, name);
    
    node->prev = node->next = NULL;
    return node;
}

额外注意事项

记得在释放链表节点时,要先释放filename的内存,再释放节点本身,避免内存泄漏:

void file_node_free(struct file_node *node) {
    free(node->filename);
    free(node);
}

修改后,每个节点的文件名都存储在独立的内存块中,不会被readdir的缓冲区覆盖,file_list_tostring就能正确遍历并拼接所有文件名了。

内容的提问来源于stack exchange,提问作者Robb1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:51:27