我试图理解通用列表在C中是如何工作的。我制作了 add 函数(在列表的开头添加了节点),这个函数非常好但是我被卡住了在摧毁清单。有些东西不能在 destroy_all_myList 中工作,因为我得到了段错误。 我已经附加了我的添加功能,因为我认为可能存在问题。
#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
如果我没有调用销毁功能,我的主就有效。
#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);
}
答案 0 :(得分: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()
使用给定内容(code)创建一个“节点”。
ft_lstdelone()
删除单个节点,其中del
指向函数的指针负责释放内容(您可能有一个具有多个分配的结构,因此您必须释放每个已分配的结构元素,而不仅仅是内容本身)(code)
ft_lstdel()
删除整个列表。 (code)
void ft_lst_push_front(t_list **first, t_list *new);
此函数在给定列表的开头添加new
元素。 (code)
使用该设置,您可以执行以下操作:
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);
答案 1 :(得分:0)
我编辑了我的代码,现在它看起来像这样:
在主中,我将数据声明为整数。
(not (prefix field=example ''))
在添加功能中,我删除了没有任何意义的数据大小的内容,现在 destroy 功能正常工作。我检查了valgrind,现在似乎没有内存泄漏。
#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);
}
答案 2 :(得分:0)
我过去曾经有过类似的问题。它使用宏。
这是一个例子: 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指针的数组[10]的链表,并开始像动态数组一样自动运行。
我为多线程测试了它,它的工作原理。虽然它看起来很复杂,但值得研究一下如何处理这样的一般问题。