[英]Free Generic Linked List
我试图了解通用列表在C中的工作方式。我制作了add函数(在列表的开头添加节点),该函数工作得很好,但我被困在破坏列表中。 自己是不是在destroy_all_myList工作,因为我得到一个段错误 。 我附加了add函数,因为我认为可能存在问题。
#include "myList.h"
#include <stdlib.h>
#include <stdio.h>
void add_myList(struct myList **head_list, void *data)
{
size_t dataSize;
struct myList *newNode;
dataSize = sizeof(data);
newNode = malloc(sizeof(struct myList));
newNode->data = malloc(sizeof(dataSize));
newNode->data = data;
newNode->next = *head_list;
*head_list = newNode;
}
void destroy_all_myList(struct myList **head_list)
{
struct myList *newNode;
while (*head_list)
{
newNode = (*head_list)->next;
free((*head_list)->data);
free(*head_list);
*head_list = newNode;
}
}
有我的头文件:
#ifndef MYLIST_H
#define MYLIST_H
struct myList
{
struct myList *next;
void *data;
};
void add_myList(struct myList **head_list, void *data);
void destroy_all_myList(struct myList **head_list);
#endif
如果不调用destroy函数,则可以使用我的main工具 。
#include <stdio.h>
#include "myList.h"
#include <stdlib.h>
int main ()
{
struct myList *list = NULL;
void *data;
*(int*)data = 5;
add_myList(&list, data);
add_myList(&list, data);
add_myList(&list, data);
//destroy_all_myList(&list);
return (0);
}
我注意到的第一件事是您没有分配正确数量的数据。 您分配的sizeof(void *)字节为8个字节,但是对于int来说就可以了,因为sizeof(int)为4字节。 如果您需要更多数据怎么办? 因此,您应该传递需要分配的数据量。
我在您的代码中发现了多个错误,因此让我更容易显示一些代码:
我还要添加内容(数据)大小,在某些情况下可能需要它。
typedef struct s_list
{
void *content;
size_t content_size;
struct s_list *next;
} t_list;
t_list *ft_lstnew(void const *content, size_t content_size);
void ft_lstdelone(t_list **alst, void (*del)(void*, size_t));
void ft_lstdel(t_list **alst, void (*del)(void *, size_t));
ft_lstnew()
创建具有给定内容( 代码 )的单个“节点”。
ft_lstdelone()
删除一个节点,其中指向函数的del
指针负责释放内容(您可能拥有具有多个分配的结构,因此必须释放每个分配的结构元素,而不仅仅是内容本身)( 代码 )
ft_lstdel()
删除整个列表。 ( 代码 )
void ft_lst_push_front(t_list **first, t_list *new);
此函数将new
元素添加到给定列表的开头。 ( 代码 )
通过该设置,您可以执行以下操作:
typedef struct s_some_data
{
char *name;
char *surname;
} t_some_data;
...
t_some_data *new_data(char const *name, char const *surname)
{
static t_some_data result;
result->name = strdup(name);
result->surname = strdup(surname);
return (&result);
}
...
//No need of the data size in this case
void delete_data(t_some_data *data)
{
free(data->name);
free(data->surname);
free(data);
}
...
t_list *head = NULL;
ft_lst_push_front(&head, ft_lstnew(new_data("A", "B"), sizeof(t_some_data));
ft_lst_push_front(&head, ft_lstnew(new_data("C", "D"), sizeof(t_some_data));
ft_lstdel(&head, (void (*)(void*, size_t))&delete_data);
我编辑了代码,现在看起来像这样:
我主要声明数据为整数。
#include <stdio.h>
#include "myList.h"
#include <stdlib.h>
int main ()
{
struct myList *list = NULL;
int data = 5;
add_myList(&list, &data);
add_myList(&list, &data);
add_myList(&list, &data);
destroy_all_myList(&list);
return (0);
}
在添加函数中,我删除了没有意义的数据大小的东西,现在销毁函数起作用了。 我检查了valgrind,现在似乎没有内存泄漏。
#include "myList.h"
#include <stdlib.h>
#include <stdio.h>
void add_myList(struct myList **head_list, void *data)
{
struct myList *newNode;
newNode = malloc(sizeof(struct myList));
newNode->data = data;
newNode->next = *head_list;
*head_list = newNode;
}
void destroy_all_myList(struct myList **head_list)
{
struct myList *newNode;
while (*head_list)
{
newNode = (*head_list)->next;
free(*head_list);
*head_list = newNode;
}
}
过去一段时间,我曾处理过类似的问题。 它使用宏。
这是一个例子: https : //github.com/ojmakke/ojlib/blob/master/ojllist/ojllist.h
您可以通过调用宏声明一个链表,例如int:
OJLIST(int,0)
这使您可以创建一个链表,并推送到链表,并使用以下功能从链表中获取:
ojllistint_create
ojllistint_push
ojllistint_get
如果您声明为:
OJLIST(struct YourStruct* ,10)
然后,您将获得指向YourStruct的指针的数组array [10]的链接列表,并像动态数组一样自动开始表现。
我对其进行了多线程测试,并且可以正常工作。 尽管它看起来很复杂,但是值得一看的是您如何解决这种普遍问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.