包含结构的自由链表包含结构
Free linked list containing structures containing structures
这是给学校的。
我正在研究 Unix 'ls' 命令的实现。为此,我每次读取目录时都使用链表(如果未设置 -R 选项,则只使用一次)。为此,我必须使用链表函数和节点(或元素,我不确定正确的名称是什么。)我们必须在以前的项目中编写代码。这些节点看起来像这样:
typedef struct s_list
{
void *content;
size_t content_size;
struct s_list *next;
}t_list;
在我的 ls 程序中,我使用这些来存储我列出的目录中的每个文件的名称和统计信息,这些信息是通过 stat() 函数获得的。所以我的t_list的'content'指针是这个结构:
typedef struct s_entry
{
char *filename;
struct stat filestat;
}t_entry;
一切正常,我遇到的唯一问题是 Valgrind 告诉我用于分配那些 t_entry 结构的 malloc() 存在泄漏。所以我想我释放它们是错误的。我是这样做的:
void free_list(t_list *entries)
{
t_list *n_node;
if (!entries)
return ;
while (entries)
{
n_node = entries->next;
free(entries->content);
free(entries);
entries = n_node;
}
}
我猜仅仅释放 *content 指针是不够的,但我尝试了其他方法,但它不起作用。如果我尝试释放 like
free(entries->content->filename);
例如,它不起作用,内容是空指针这一事实在我试图解决问题的某些方面似乎是个问题,但这就是我们必须对这些链表进行编码的方式函数。
如果有人能给我一些关于如何正确释放这些列表的提示,那就太棒了,因为我真的坚持这一点。提前致谢。
对不起,如果我的英语或解释不够清楚。
ps:为了以防万一,整个项目(远未完成)可以在这里找到:
https://github.com/Zestx/ft_ls
您需要转换数据以便编译器知道在哪里可以找到结构成员,这里是一个完整的示例:
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
typedef struct s_list
{
void *content;
size_t content_size;
struct s_list *next;
}t_list;
typedef struct s_entry
{
char *filename;
struct stat filestat;
}t_entry;
int main(void)
{
t_list *foo = malloc(sizeof *foo);
t_entry *bar = malloc(sizeof *bar);
bar->filename = malloc(10);
foo->content = bar;
free(((t_entry *)foo->content)->filename);
free(foo->content);
free(foo);
return 0;
}
如果您有目录中每个文件的 ls
条目列表,其中 content
是指向包含文件名和 stat
信息的已分配 t_entry
的指针,例如
typedef struct s_list {
void *content;
size_t content_size;
struct s_list *next;
} t_list;
和
typedef struct s_entry {
char *filename;
struct stat filestat;
} t_entry;
freelist (t_list *head)
函数需要遍历每个节点,并且:
free
filename
分配在每个 t_entry
内;
free
分配t_entry
;最后
free
t_list
节点本身。
您可以执行类似以下操作:
void freelist (t_list *head)
{
t_list *node = head; /* temporary node to iterate list */
/* (you could use head, but don't) */
while (*node) {
t_list *victim = node; /* pointer to current node to free */
t_entry *entry = node->content; /* pointer to content */
free (entry->filename) /* free content->filename */
free (entry); /* free t_entry struct itself */
node = node->next; /* advance before freeing victim */
free (victim); /* free current t_list node (victim) */
}
}
注意上面,而不是使用 node
,你可以简单地使用 head
来迭代,因为 freelist
收到一个无论如何都不会改变列表地址的副本——并且因为那里完成后将没有列表,但是使用临时节点迭代列表(在任何函数中)是一个更好的习惯,这样您在处理实际列表地址(例如参数是 t_list **
) 或指针的副本(参数是 t_list *
)。
检查一下,如果您还有其他问题,请告诉我。
这是给学校的。
我正在研究 Unix 'ls' 命令的实现。为此,我每次读取目录时都使用链表(如果未设置 -R 选项,则只使用一次)。为此,我必须使用链表函数和节点(或元素,我不确定正确的名称是什么。)我们必须在以前的项目中编写代码。这些节点看起来像这样:
typedef struct s_list
{
void *content;
size_t content_size;
struct s_list *next;
}t_list;
在我的 ls 程序中,我使用这些来存储我列出的目录中的每个文件的名称和统计信息,这些信息是通过 stat() 函数获得的。所以我的t_list的'content'指针是这个结构:
typedef struct s_entry
{
char *filename;
struct stat filestat;
}t_entry;
一切正常,我遇到的唯一问题是 Valgrind 告诉我用于分配那些 t_entry 结构的 malloc() 存在泄漏。所以我想我释放它们是错误的。我是这样做的:
void free_list(t_list *entries)
{
t_list *n_node;
if (!entries)
return ;
while (entries)
{
n_node = entries->next;
free(entries->content);
free(entries);
entries = n_node;
}
}
我猜仅仅释放 *content 指针是不够的,但我尝试了其他方法,但它不起作用。如果我尝试释放 like
free(entries->content->filename);
例如,它不起作用,内容是空指针这一事实在我试图解决问题的某些方面似乎是个问题,但这就是我们必须对这些链表进行编码的方式函数。
如果有人能给我一些关于如何正确释放这些列表的提示,那就太棒了,因为我真的坚持这一点。提前致谢。 对不起,如果我的英语或解释不够清楚。
ps:为了以防万一,整个项目(远未完成)可以在这里找到: https://github.com/Zestx/ft_ls
您需要转换数据以便编译器知道在哪里可以找到结构成员,这里是一个完整的示例:
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
typedef struct s_list
{
void *content;
size_t content_size;
struct s_list *next;
}t_list;
typedef struct s_entry
{
char *filename;
struct stat filestat;
}t_entry;
int main(void)
{
t_list *foo = malloc(sizeof *foo);
t_entry *bar = malloc(sizeof *bar);
bar->filename = malloc(10);
foo->content = bar;
free(((t_entry *)foo->content)->filename);
free(foo->content);
free(foo);
return 0;
}
如果您有目录中每个文件的 ls
条目列表,其中 content
是指向包含文件名和 stat
信息的已分配 t_entry
的指针,例如
typedef struct s_list {
void *content;
size_t content_size;
struct s_list *next;
} t_list;
和
typedef struct s_entry {
char *filename;
struct stat filestat;
} t_entry;
freelist (t_list *head)
函数需要遍历每个节点,并且:
free
filename
分配在每个t_entry
内;free
分配t_entry
;最后free
t_list
节点本身。
您可以执行类似以下操作:
void freelist (t_list *head)
{
t_list *node = head; /* temporary node to iterate list */
/* (you could use head, but don't) */
while (*node) {
t_list *victim = node; /* pointer to current node to free */
t_entry *entry = node->content; /* pointer to content */
free (entry->filename) /* free content->filename */
free (entry); /* free t_entry struct itself */
node = node->next; /* advance before freeing victim */
free (victim); /* free current t_list node (victim) */
}
}
注意上面,而不是使用 node
,你可以简单地使用 head
来迭代,因为 freelist
收到一个无论如何都不会改变列表地址的副本——并且因为那里完成后将没有列表,但是使用临时节点迭代列表(在任何函数中)是一个更好的习惯,这样您在处理实际列表地址(例如参数是 t_list **
) 或指针的副本(参数是 t_list *
)。
检查一下,如果您还有其他问题,请告诉我。