当前位置: 首页 > 知识库问答 >
问题:

删除null终止的双链表中的所有节点

东郭俊楠
2023-03-14

该代码适用于较小的输入,但对于非常大的输入,它会给出损坏的大小与前缀大小的错误

>>Input1 : 12312312312123123123123123123123
>>Input2 : 1
>>Addition : 12312312312123123123123123123124
>>Inside Destroy
*** Error in `./savan': corrupted size vs. prev_size: 0x0000000002066c40 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7f88ba43a7e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x83781)[0x7f88ba446781]
/lib/x86_64-linux-gnu/libc.so.6(realloc+0x179)[0x7f88ba447839]
./savan[0x401073]
./savan[0x401369]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f88ba3e3830]
./savan[0x400749]

这是我销毁所有节点和结构定义的代码。

结构定义

typedef struct node{
        char ch;
        struct node *next,*prev;
}node;

typedef struct Integer{
        node *p, *q;
}Integer;
 void destroyInteger(Integer *a){
    node *tmp = NULL;
    printf("Inside Destroy");
        if(a->p == NULL) //if the Integer is empty then do nothing
            return;
        while(a->p->next != NULL){ //while integer's next not null loop
            tmp = a->p;        //assign to temp and free it
            a->p = a->p->next; // move the pointer ahead
            free(tmp);
        }
        tmp = a->p; //for last node or if only one node as it is double null terminated list
        free(tmp);  
        a->p = NULL; //make the integer null as in initInteger
        a->q = NULL;
    }
#include<stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <limits.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include<unistd.h>
#include<string.h>
#include<ctype.h>
#include "integer.h"
void initInteger(Integer *a){
    a->p = NULL;
    a->q = NULL;
}

void addDigit(Integer *a, char c){
    node *temp;
    if(isdigit(c)){
        temp = (node*)malloc(sizeof(node));
        temp->ch = c;
        temp->next = NULL;
        if(a->p == NULL){
            temp->prev = NULL;
            a->p = temp;
            a->q = temp;
        }
        else{
            a->q->next = temp;
            temp->prev = a->q;  
            a->q = temp;
        }
    }
    else
        return;
}
void printInteger(Integer a){
    char c;
    if(a.p == NULL){
        printf("0\n");
        return;
    }
    while(a.p->next != NULL){
        c = a.p->ch;
        putchar(c);
        a.p = a.p->next;
    }
    c = a.p->ch;
    putchar(c);
    putchar('\n');
}
Integer createIntegerFromString(char *str){
    int i = 0, flag = 0;
    char ch;
    Integer res;
    initInteger(&res);
    while(*(str + i) != '\0'){
        if(isdigit(*(str + i))){
            ch = *(str + i);
            addDigit(&res, ch);
            flag = 1;
            i++;
        }
        else
            break;          
    }   
    if(flag == 0){
        addDigit(&res, '0');
    }
    return res;
}
Integer addIntegers(Integer a, Integer b){
    Integer c;
    char num1, num2, *revString = (char*)malloc(sizeof(char));
    int n1, n2, carry = 0, counter = 0, sum = 0, flag1 = 0, flag2 = 0, mainflag = 0, i;
    initInteger(&c);
    if(a.p == NULL && b.p == NULL){
        addDigit(&c, '0');
        return c;
    }
    else if(a.p == NULL && b.p != NULL)
        return b;       
    else if(a.p != NULL && b.p == NULL)
        return a;

    else{
        do{     n1 = n2 = 0;
            num1 = num2 = '\0';
            if(a.q->prev == NULL && b.q->prev == NULL)
                mainflag = 1;
            //for a
            if(a.q->prev == NULL && flag1 == 0){
                num1 = a.q->ch;
                n1 = num1 - '0';
                flag1 = 1;
            }
            else if(a.q->prev != NULL){
                num1 = a.q->ch;
                n1 = num1 - '0';
                a.q = a.q->prev;
            }
            else
                n1 = 0;
            //for b
            if(b.q->prev == NULL && flag2 == 0){
                num2 = b.q->ch;
                n2 = num2 - '0';
                flag2 = 1;      
            }
            else if(b.q->prev != NULL){
                num2 = b.q->ch;
                n2 = num2 - '0';
                b.q = b.q->prev;
            }
            else
                n2 = 0; 
            sum = n1 + n2 + carry;
            if(sum >=  10){
                revString[counter++] = (sum % 10) + '0';
                carry = 1;
                sum = 0;
            }
            else{
                revString[counter++] = sum + '0';
                carry = 0;
            }
        revString = (char*)realloc(revString, counter + 1);
        }while(mainflag != 1);
        if(carry == 1){
            revString[counter++] = '1';
        }
        for(i = counter; i > 0; i--){
            addDigit(&c, revString[i-1]);
        }
    }
    free(revString);
    return c;
}
Integer substractIntegers(Integer a, Integer b){
    Integer c;
    char num1, num2, *revString = (char*)malloc(sizeof(char));
    int n1, n2, carry = 0, counter = 0, sum = 0, flag1 = 0, flag2 = 0, mainflag = 0, i, len1, len2;
    len1 = length(a);
    len2 = length(b);
    initInteger(&c);
    if(len1 < len2){
        addDigit(&c, '0');
        return c;
    }
    if(a.p == NULL && b.p == NULL){
        addDigit(&c, '0');
        return c;
    }
    else if(a.p == NULL && b.p != NULL)
        return b;       
    else if(a.p != NULL && b.p == NULL)
        return a;

    else{
        do{     n1 = n2 = 0;
            num1 = num2 = '\0';
            if(a.q->prev == NULL && b.q->prev == NULL)
                mainflag = 1;
            //for a
            if(a.q->prev == NULL && flag1 == 0){
                num1 = a.q->ch;
                n1 = num1 - '0';
                flag1 = 1;
            }
            else if(a.q->prev != NULL){
                num1 = a.q->ch;
                n1 = num1 - '0';
                a.q = a.q->prev;
            }
            else
                n1 = 0;
            //for b
            if(b.q->prev == NULL && flag2 == 0){
                num2 = b.q->ch;
                n2 = num2 - '0';
                flag2 = 1;      
            }
            else if(b.q->prev != NULL){
                num2 = b.q->ch;
                n2 = num2 - '0';
                b.q = b.q->prev;
            }
            else
                n2 = 0; 
            sum = n1 - n2 - carry;
            if(sum <  0){
                sum += 10;
                revString[counter++] = sum  + '0';
                carry = 1;
                sum = 0;
            }
            else{
                revString[counter++] = sum + '0';
                carry = 0;
            }
        revString = (char*)realloc(revString, counter);
        }while(mainflag != 1);

        if(carry == 1){
            revString[counter++] = '1';
        }
        for(i = counter; i > 0; i--){
            addDigit(&c, revString[i-1]);
        }
    }
    free(revString);
    return c;
}
int length(Integer l) {
    int len = 0;
    node *tmp;
    tmp = l.p;
    if(!tmp)
        return 0;
    while(tmp->next != NULL){
        tmp = tmp->next;
        len++;
    }
    return len+1;
}
void destroyInteger(Integer *a){
    node *tmp = NULL;
    if(a->p == NULL)
        return;
    while(a->p->next != NULL){
        tmp = a->p;
        a->p = a->p->next;
        free(tmp);
    }
    tmp = a->p;
    a->p = NULL;
    a->q = NULL;
    free(tmp);
}
Integer a, b, c;
    char ch;
    char str[64]; /* This size may change */

    initInteger(&a);
    initInteger(&b);

    while((ch = getchar()) != '\n')
        addDigit(&a, ch);
    scanf("%s", str);
    b = createIntegerFromString(str);
    c = addIntegers(a, b); 
    printInteger(c);
    destroyInteger(&c);
typedef struct node{
    char ch;
    struct node *next,*prev;
}node;

typedef struct Integer{
    node *p, *q;
}Integer;

/*Functions*/
void initInteger(Integer *a);
void addDigit(Integer *a, char c);
void printInteger(Integer a);
Integer createIntegerFromString(char *str);
Integer addIntegers(Integer a, Integer b);
Integer substractIntegers(Integer a, Integer b);
void destroyInteger(Integer *a);
int length(Integer a);

共有1个答案

全丰
2023-03-14

我注意到的一件事是addintegers中的这段代码:

else if(a.p == NULL && b.p != NULL)
    return b;       

如果设置

c = addIntegers(a, b)

这段代码将使C成为B的副本,但是CB都指向相同的节点。如果随后销毁C(或B),则另一个将有指向释放内存的指针,这是失败的原因。

 类似资料:
  • 这是我的remove函数,用于删除具有元素的节点。我得到了一个seg错误,我很确定这是因为temp->prev是前面的哨兵,所以从技术上来说,它不在双链表中。如果这是正确的,我实际上如何防止这种情况?如有任何帮助,不胜感激。 编辑:刚刚更新了代码,但仍然出现了Seg错误

  • 双链表节点是在main函数中创建的。Ender和header已定义。在删除节点函数处中断-ender为空。 释放最后一个和第一个输入的内存的最佳方法是什么,即:删除:233,A和888,F?

  • 我试图从基于阉羊的双链表中删除一个元素,该列表中的节点满足返回bool的函数。由于某种原因,替换节点的前一个指针(下一个被删除)不更新,而是引用回它自己。 我的代码 测试结果

  • 我有麻烦删除双向链表中的节点,程序崩溃,我不能解决这个问题。你能帮我吗?这是创建新节点,查看它们并删除它们的完整代码。 我认为这个问题与Node del的scanf()有关,但我不确定。当我只是通过或

  • 我写了下面的代码,但它在执行create()函数后停止工作。我想从头节点开始删除替代元素。我的delete_Alt()函数正确吗?请告诉我哪里错了。

  • 以下代码删除双链接列表中的第一个节点。 如果列表只包含1个元素,我们将last的引用设置为null。我的问题是,我们为什么不将first的引用设置为null?这会有什么不同吗?