免费通用链接列表

时间:2017-09-07 16:21:35

标签: c linked-list

我试图理解通用列表在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);
}

3 个答案:

答案 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]的链表,并开始像动态数组一样自动运行。

我为多线程测试了它,它的工作原理。虽然它看起来很复杂,但值得研究一下如何处理这样的一般问题。