链表只是偶尔给出 segv
Linked list gives segv only occasionally
我需要实现一个链表,将文件名和信息存储为每个节点。
我决定将节点填充为:
struct node
{
struct stat st;
char filename[FILENAME_MAX];
struct node *next;
};
我希望我的程序根据任何给定目录中的文件名创建一个链接列表。
我已经做了几个函数来完成这个。
(xmalloc 只是 malloc 的包装器,如果 malloc returns null 由于某种原因退出程序)
将节点添加到现有列表:
struct node *
add_list(struct node **head, struct node n)
{
struct node *new = xmalloc(sizeof(struct node));
memcpy(new, &n, sizeof(struct node));
new->next = NULL;
new->next = *head;
*head = new;
return new;
}
正在用给定目录中的文件填充列表:
int
fill_list(struct node **head, const char *dirname)
{
DIR *dir;
struct dirent *de;
if ((dir = opendir(dirname)) == NULL)
{
perror("(fill_list) opendir");
free_list(head);
exit(EXIT_FAILURE);
}
while (de = readdir(dir))
{
// Don't add entries for parent dir and current fir
if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
continue;
struct node new_node;
new_node.next = NULL;
strncpy((new_node.filename), (de->d_name), FILENAME_MAX);
stat(de->d_name, &(new_node.st));
add_list(head, new_node);
}
}
释放现有列表:
free_list(struct node** head)
{
struct node* current = *head;
struct node* next = NULL;
while (current->next != NULL)
{
next = current->next;
printf("free: %p\n", current);
current = next;
}
*head = NULL;
}
最后,打印列表的内容:
int
print_list(struct node *head)
{
while (head->next)
{
printf("%s: %ld\n", head->filename, head->st.st_size);
head = head->next;
}
}
我的主要功能是
int main(void)
{
struct node *head;
fill_list(&head, ".");
print_list(head);
free_list(&head);
}
出于某种原因,当我 运行 这段代码时,我有时会遇到分段错误,但并非总是如此。
我的目录包含
a.out list.h llist.c log_synfiles.log syncfiles syncfiles.c test.c
当 运行 正常时,就会出现内存泄漏。
为什么会这样?
For some reason, when I run this code, I get a segmentation fault sometimes, not always.
使用 Memory Sanitizer 构建您的程序,运行 它产生:
==11652==WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x49a500 in print_list /tmp/t.c:74:5
#1 0x49a704 in main /tmp/t.c:86:5
#2 0x7f8815606e49 in __libc_start_main csu/../csu/libc-start.c:314:16
#3 0x41f269 in _start (/tmp/a.out+0x41f269)
第 74 行是:
72 print_list(struct node *head)
73 {
74 while (head->next)
75 {
76 printf("%s: %ld\n", head->filename, head->st.st_size);
77 head = head->next;
78 }
79 }
发生这种情况是因为您“链接”到 main
中定义的 head
,但 head
本身从未初始化。修复:
81 int main(void)
82 {
83 struct node *head = NULL; // <<<--- initialize it.
84 fill_list(&head, ".");
And the times when it runs properly, there's a memory leak.
当然有:
34 while (current->next != NULL)
35 {
36 next = current->next;
37 printf("free: %p\n", current);
--->>> free(current); // Did you intend to free memory here?
38 current = next;
39 }
--->>> free(current); // Also need to free the last node.
40
41 *head = NULL;
42 }
您还必须调用 closedir()
来释放 opendir()
分配的 DIR
。
我需要实现一个链表,将文件名和信息存储为每个节点。 我决定将节点填充为:
struct node
{
struct stat st;
char filename[FILENAME_MAX];
struct node *next;
};
我希望我的程序根据任何给定目录中的文件名创建一个链接列表。 我已经做了几个函数来完成这个。
(xmalloc 只是 malloc 的包装器,如果 malloc returns null 由于某种原因退出程序) 将节点添加到现有列表:
struct node *
add_list(struct node **head, struct node n)
{
struct node *new = xmalloc(sizeof(struct node));
memcpy(new, &n, sizeof(struct node));
new->next = NULL;
new->next = *head;
*head = new;
return new;
}
正在用给定目录中的文件填充列表:
int
fill_list(struct node **head, const char *dirname)
{
DIR *dir;
struct dirent *de;
if ((dir = opendir(dirname)) == NULL)
{
perror("(fill_list) opendir");
free_list(head);
exit(EXIT_FAILURE);
}
while (de = readdir(dir))
{
// Don't add entries for parent dir and current fir
if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
continue;
struct node new_node;
new_node.next = NULL;
strncpy((new_node.filename), (de->d_name), FILENAME_MAX);
stat(de->d_name, &(new_node.st));
add_list(head, new_node);
}
}
释放现有列表:
free_list(struct node** head)
{
struct node* current = *head;
struct node* next = NULL;
while (current->next != NULL)
{
next = current->next;
printf("free: %p\n", current);
current = next;
}
*head = NULL;
}
最后,打印列表的内容:
int
print_list(struct node *head)
{
while (head->next)
{
printf("%s: %ld\n", head->filename, head->st.st_size);
head = head->next;
}
}
我的主要功能是
int main(void)
{
struct node *head;
fill_list(&head, ".");
print_list(head);
free_list(&head);
}
出于某种原因,当我 运行 这段代码时,我有时会遇到分段错误,但并非总是如此。
我的目录包含
a.out list.h llist.c log_synfiles.log syncfiles syncfiles.c test.c
当 运行 正常时,就会出现内存泄漏。
为什么会这样?
For some reason, when I run this code, I get a segmentation fault sometimes, not always.
使用 Memory Sanitizer 构建您的程序,运行 它产生:
==11652==WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x49a500 in print_list /tmp/t.c:74:5
#1 0x49a704 in main /tmp/t.c:86:5
#2 0x7f8815606e49 in __libc_start_main csu/../csu/libc-start.c:314:16
#3 0x41f269 in _start (/tmp/a.out+0x41f269)
第 74 行是:
72 print_list(struct node *head)
73 {
74 while (head->next)
75 {
76 printf("%s: %ld\n", head->filename, head->st.st_size);
77 head = head->next;
78 }
79 }
发生这种情况是因为您“链接”到 main
中定义的 head
,但 head
本身从未初始化。修复:
81 int main(void)
82 {
83 struct node *head = NULL; // <<<--- initialize it.
84 fill_list(&head, ".");
And the times when it runs properly, there's a memory leak.
当然有:
34 while (current->next != NULL)
35 {
36 next = current->next;
37 printf("free: %p\n", current);
--->>> free(current); // Did you intend to free memory here?
38 current = next;
39 }
--->>> free(current); // Also need to free the last node.
40
41 *head = NULL;
42 }
您还必须调用 closedir()
来释放 opendir()
分配的 DIR
。