目录条目和链表

Directory entries and linked lists

这是将目录条目字符串(在本例中是从根目录)放入单链表的代码。我不明白为什么在这样评论的行会出现段错误。我一定是字符串复制错了?

我只能认为space for the string to go has not been reserved,但我以为我已经被tmp1 = (struct node *)malloc(sizeof(struct node));保留了?

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>

struct node {
    struct dirent *ent;
    struct node *right;
};

void appendnode(struct node **, struct dirent **);

int main() {
    DIR *d;
    struct dirent *d_ent;
    struct node *list;
    list = NULL;
    d = opendir("C:/");
    d_ent = readdir(d);
    while (d_ent) {
        appendnode(&list, &d_ent);
        d_ent = readdir(d);
    }
    getchar();
    return 0;
}

void appendnode(struct node **q, struct dirent **r) {
    struct node *tmp1, *tmp2;
    tmp1 = (struct node *)malloc(sizeof(struct node));
    strcpy(tmp1 -> ent -> d_name, (*r) -> d_name);  // <-- Causes seg fault. Why?
    tmp1 -> right = NULL;
    if (!*q) {
        *q = tmp1;
    } else {
        tmp2 = *q;
        while (tmp2 -> right) {
            tmp2 = tmp2 -> right;
        }
        tmp2 -> right = tmp1;
    }
}
struct node {
    struct dirent *ent;
    struct node *right;
};

tmp1 = (struct node *)malloc(sizeof(struct node));

在调用 malloc 之前打印 sizeof(struct node) 并查看它显示了多少。您在这里所做的是为 pointer 分配内存以构造 dirent,并为 pointer 分配内存以构造节点。根据您 运行 使用的系统,每个指针的大小为 4 字节或 8 字节。您需要为每个节点中的每个目录条目分配内存,并使用指针指向该条目。

仔细查看您的代码,我不太确定您要实现的目标是什么。修复内存分配问题后,您粘贴的代码将陷入无限循环。我建议你拿笔和纸逐步了解程序以了解发生了什么。

您遇到分段错误是因为您试图访问一个未初始化的指针 tmp1->ent:

strcpy(tmp1 -> ent -> d_name, (*r) -> d_name);
               ^^^

分配内存给tmp1后,你还应该分配内存给tmp1->ent

tmp1->ent = malloc(sizeof(struct dirent));
if (tmp1->ent == NULL) {
    fprintf (stderr, "Failed to allocate memory");
    exit(EXIT_FAILURE);
}

此外,您不需要施放 malloc return。遵循良好的编程习惯,始终检查 NULL 指向尝试分配内存的指针。你应该做

if (tmp1 == NULL) {
    fprintf (stderr, "Failed to allocate memory");
    exit(EXIT_FAILURE);
}