如何正确打印链表的成员

时间:2013-11-26 13:43:51

标签: c linux gcc linked-list

我正在使用链表来递归地获取目录中所有文件的列表。

但由于某种原因,我无法浏览列表以打印所有节点的名称。 行printf("%s\n", p->name);的输出只是垃圾。编译时还有两个警告。我在下面的代码中用注释标记了这些行。

以下是代码:

typedef struct {
    char *name;
    struct FileList *next;
} FileList;

FileList *head = NULL;
FileList *cur = NULL;
long int totalSize = 0;

FileList* appendToFileList(char *name) {
    FileList *ptr = (FileList*) malloc(sizeof(FileList));

    if (ptr != NULL) {
        ptr->name = name;
        ptr->next = NULL;
        if (head == NULL) { //if its the first value add it to the head node
            head = cur = ptr;
            printf("added value to head %s\n", head->name); //this statement works correctly
        } else {
            cur->next = ptr; //warning "warning: assignment from incompatible pointer type" here
            cur = ptr;
            printf("added value %s\n", cur->name); //this statement works correctly
        }
    } else {
        return NULL;
    }
    return ptr;
}

int ftwCallback(char *file, struct stat *info, int flag) {
    if(flag == FTW_F) { //if entry is a file
        appendToFileList(file);
        totalSize += info->st_size;
    }
    return 0;
}

int main(int argc, char **argv) {
    //this function walks a given directory recursively and calls "ftwcallback" for each entry
    ftw(argv[1], ftwCallback, getdtablesize() - 1);
    FileList *p = head;

    while (p->next != NULL) {
        printf("%s\n", p->name); //just garbage here
        p = p->next; //warning "warning: assignment from incompatible pointer type" here
    }
    printf("Total size: %d\n", totalSize);

    return 0;
}

我采用了this示例中的一些代码。

这里出了什么问题?

3 个答案:

答案 0 :(得分:1)

这是因为你永远不会为名称分配内存,只需保留调用者的指针。

如果来电者的指针不再有效,那么你的副本也是如此。

您必须将字符串存储在节点内,或者至少动态分配内存才能这样做。

另外,please don't cast the return value of malloc() in C

答案 1 :(得分:1)

您需要执行strcpy而非下面的作业

旧代码

ptr->name = name;

新代码

ptr->name = malloc(strlen(name)+1);
strcpy(ptr->name, name);

在旧代码中,name是堆栈中包含字符串的临时指针。因此,该指针可能会为函数appendToFileList的每次新调用获取一个新值。因此,当您尝试打印ptr->name时,它指向无效的位置。因此,这保证了新代码中建议的内存分配和后续复制。

答案 2 :(得分:0)

问题不在于打印,而在于存储值。

您只需复制传递给appendToFileList方法的值即可。 char *指向在其范围丢失后重用的内存区域。 malloc一个足够大的内存区域,strcpy文件名,并存储指向“malloced”区域的指针。