我正在使用链表来递归地获取目录中所有文件的列表。
但由于某种原因,我无法浏览列表以打印所有节点的名称。
行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示例中的一些代码。
这里出了什么问题?
答案 0 :(得分:1)
这是因为你永远不会为名称分配内存,只需保留调用者的指针。
如果来电者的指针不再有效,那么你的副本也是如此。
您必须将字符串存储在节点内,或者至少动态分配内存才能这样做。
答案 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”区域的指针。