【问题标题】:C - Popping last item from linked listsC - 从链表中弹出最后一项
【发布时间】:2015-05-19 18:21:57
【问题描述】:

我正在学习链表,它们给我带来了很多麻烦。 我用这个调用来调用函数:

pop(&list);

这是代码:

void pop(NODE** first) {
if(*first != NULL && first!= NULL){
    NODE* ptr = *first;
    while(ptr->next->next != NULL){
        ptr = ptr->next;
    }
    free(ptr->next);
    ptr->next = NULL;   
}

即使我一次调用它也会导致内存泄漏错误..

多次调用该函数时,内存泄漏错误较多。

提前致谢,Mimpopo。

编辑:节点的定义

typedef struct node {
    int data;
    struct node *next;
} NODE;

完整代码:

    #include <stdio.h>
#include <stdlib.h>

typedef struct node {
    int data;
    struct node *next;
} NODE;



NODE* insert(NODE *first, int n){
    // create new node
    NODE* new = (NODE*)malloc(sizeof(NODE));
    new->data = n;
    new->next = NULL;

    // if first is NULL, this will be the first
    if(first == NULL)
        return new;

     // otherwise, place it correctly
     NODE* ptr = first;

     // check inserting at the begining
     if(ptr->data > new->data){
        new->next = ptr;
        return new;
     }

     // insert in the middle
     while(ptr->next != NULL){
        if(ptr->next->data > n && ptr->data < n){
            new->next = ptr->next;
            ptr->next = new;
            break;
        }
        ptr = ptr->next;
     }

     // insert at the end of list
     if(ptr->next == NULL){
         ptr->next = new;
     }

    return first;
}

void traverse(NODE *first){
    NODE* ptr = first;
    while(ptr != NULL){
        printf("%d\n", ptr->data);
        ptr = ptr->next;
    }   
}   

NODE* search(NODE *first, int n){
    NODE* ptr = first;
    while(ptr != NULL){
        if(ptr->data == n){
            printf("FOUND %d\n!", n);
            return ptr;
        }
    ptr = ptr->next;
    }
}

int main(){
    NODE* first = NULL;
    NODE* this = NULL;
    first = insert(first, 7);
    first = insert(first, 10);
    first = insert(first, 11);
    first = insert(first, 1);
    first = insert(first, 3);
    first = insert(first, 5);
    first = insert(first, 22);
    first = insert(first, 23);
    first = insert(first, 24);
    first = insert(first, 125);

    pop(&first);




}

【问题讨论】:

  • 请在您的问题中添加NODE 的声明以及调用pop 的代码。
  • “内存泄漏错误”到底是什么意思?
  • 我看到的一个问题是,如果first 只包含一条记录,while(ptr-&gt;next-&gt;next != NULL) 会导致段错误。
  • ptr-&gt;next-&gt;next 在您没有检查 ptr-&gt;nextNULL总是错误。注意你已经发布了两个不同的pop() 函数。
  • *first != NULL &amp;&amp; first!= NULL 应该相反。你可以访问first,即使它是NULL

标签: c list pointers structure


【解决方案1】:

我没有看过你所有的代码,但至于函数,可以这样写

void pop( NODE ** first ) 
{
    if ( *first != NULL )
    {
        NODE *prev = NULL;
        NODE *current = *first;

        while ( current->next ) 
        {
            prev = current;
            current = current->next;
        }

        if ( prev != NULL ) prev->next = current->next;
        else ( *first = NULL );

        free( current );
    }
}

至于您的函数实现,它包含许多错误。例如在这个语句中

if(*first != NULL && first!= NULL){

你应该交换第一个和第二个比较。那就是条件应该是这样的

if(first != NULL && *first!= NULL){

在此声明中

while(ptr->next->next != NULL){

你必须确定ptr-&gt;next不等于NULL。

你也不检查删除的节点是否是列表的第一个节点。

考虑到函数插入也是错误的。您在此代码中只考虑一个条件 sn-p

 while(ptr->next != NULL){
    if(ptr->next->data > n && ptr->data < n){
        new->next = ptr->next;
        ptr->next = new;
        break;
    }
    ptr = ptr->next;
 }

不过也可以这样

    ptr->next->data >= n && ptr->data < n

    ptr->next->data > n && ptr->data <= n

【讨论】:

  • 在我的代码中:==3377== 泄漏摘要:==3377== 肯定丢失:1 个块中的 8 个字节 ==3377== 间接丢失:8 个块中的 64 个字节 ==3377= = 可能丢失:0 个块中的 0 个字节 ==3377== 仍然可以访问:0 个块中的 0 个字节 ==3377== 抑制:0 个块中的 0 个字节
  • 如果我可能会问,如果被删除的节点是列表的第一个节点,我该怎么办?
  • @Mestralx 您询问了关于弹出最后一个节点的问题。我向您展示了如何正确编写函数。所以我不明白“这对我不起作用”。我展示的功能有什么问题?
  • @Mestralx 您必须删除第一个节点并将 *first 设置为 NULL。我的意思是第一个节点是列表中唯一一个节点的情况。
  • 你的函数仍然给我 ==3540== 泄漏摘要:==3540== 肯定丢失了:7 个字节在 1 个块中
猜你喜欢
  • 1970-01-01
  • 2020-05-13
  • 1970-01-01
  • 2016-09-10
  • 1970-01-01
  • 2013-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多