简体   繁体   English

C 自由链表

[英]C free linked list

I need to know how to modify the free function to remove the first element of the list (last added).我需要知道如何修改免费的 function 以删除列表的第一个元素(最后添加)。 I must not interfere with the main function.我绝不能干扰主 function。 This is how the last element added to me remains in the list.这就是添加到我的最后一个元素保留在列表中的方式。

typedef struct TEmployee
{
    struct TEmployee *m_Next;
    struct TEmployee *m_Bak;
    char *m_Name;
} TEMPLOYEE;


TEMPLOYEE *newEmployee (const char *name, TEMPLOYEE *next)
{
    TEMPLOYEE *n = (TEMPLOYEE*) malloc(sizeof(*next));
    
    n->m_Name = (char*) malloc(sizeof(char)*100);
    strcpy(n->m_Name, name);
    n->m_Bak = NULL;
    
    n->m_Next = next;
    
    return n;
    
}


void freeList ( TEMPLOYEE *q )
{
    TEMPLOYEE *x = q;
    
    while( x != NULL)
    {
        TEMPLOYEE *tmp = x->m_Next;
        free(x);
        x = tmp;
    }
    free(x);
    x=NULL;
}

Currently, the freeList method deletes all the elements in the linked list.目前, freeList方法会删除链表中的所有元素。

To just delete the first element of a linked list, the algorithm should be as follows:只删除链表的第一个元素,算法应该如下:

  1. Given the head as the input.给定head作为输入。
  2. It could be possible that the head itself is NULL meaning the list is already empty, in that case we can simply return. head本身可能是NULL意味着列表已经为空,在这种情况下我们可以简单地返回。
  3. In the other case, we can simply set head = head->m_Next .在另一种情况下,我们可以简单地设置head = head->m_Next
  4. Now, since we also have previous pointers, we need to update the previous pointer for the current head, ie head->m_Back = NULL .现在,由于我们还有先前的指针,我们需要更新当前头的先前指针,即head->m_Back = NULL

Please try to use the above algorithm and write the updated freeList method.请尝试使用上述算法并编写更新后的freeList方法。

It cannot reliably be done without modifying the caller.如果不修改调用者,它就无法可靠地完成。

In it's basic form, you just have to free the node and trust that nobody uses it anymore:在它的基本形式中,您只需要释放节点并相信没有人再使用它:

void freeFirst ( TEMPLOYEE *q )
{
    if (q) {
        free(q->m_Name);
        free(q);
    }
}

Now to make this a bit more reliable, you should also modify the queue head node.现在为了使它更可靠一点,您还应该修改队列头节点。 This can be done by passing a double pointer to allow modification of the head node pointer:这可以通过传递一个双指针来允许修改头节点指针来完成:

void freeFirst ( TEMPLOYEE **q )
{
    TEMPLOYEE *x = *q;

    if (*q) {
        *q = (*q)->m_Next;
        free(*x->m_Name);
        free(*x);
    }
}

Now it's important that the caller is modified, instead of freeList(list) you would now need freeList(&list) .现在重要的是调用者被修改,而不是freeList(list)你现在需要freeList(&list)

Not that I have also freed the m_Name member, because otherwise you will leak the memory.并不是说我也释放了m_Name成员,否则你会泄露 memory。

You should also use strdup instead of your combination of malloc of arbitrary length and strcpy , that could cause a buffer overflow.您还应该使用strdup而不是任意长度的mallocstrcpy的组合,这可能会导致缓冲区溢出。

The problem is that you pass the pointer to the first element by value .问题是您通过value将指针传递给第一个元素。 If you want to modify the value of the head pointer, you need to pass it by reference , as in:如果要修改头指针的值,需要通过引用传递,如:

void freeList ( TEMPLOYEE **q )
{
    TEMPLOYEE *x = *q;
    
    while( x != NULL)
    {
        TEMPLOYEE *tmp = x->m_Next;
        free(x);
        x = tmp;
    }
    /* free(x); this is incorrect, tmp is already NULL when you
     * get out of the while loop
     * x=NULL;  // and this is nonsense, it's already NULL and you are not
     *          // using x anymore.
     */
    *q = NULL; /* this is what you lack, to assign NULL to the pointer. */
}

Later, you need to call freelist() as follows:稍后,您需要调用freelist()如下:

    freelist(&list_head);

to pass a reference of the pointer instead of the pointer's value.传递指针的引用而不是指针的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM