从列表(C)删除节点时出现段错误

时间:2018-08-11 13:45:06

标签: c list segmentation-fault

任务是从write中创建一个程序readfile对象,然后从其中创建一个列表,然后用奇数{{ 1}}-s。删除是通过一些嵌套函数完成的。问题是,某处存在段错误。当然,我是通过调试器运行的,但是我们都没有学过机器码/汇编语言,也没有听说过如何一起使用调试器。

Node

我包括整个代码,而不仅仅是有问题的功能,因此可以运行该程序。 我认为创建列表的方式可能是非传统的,因此我将对其进行简要说明,这样您就不必费心找出它了:
有两种类型的对象。 int没有#include <stdio.h> #include <string.h> #include <stdlib.h> #include <conio.h> typedef struct smallNode { int val; char str[10]; }smallNode; typedef struct Node { smallNode smallNode; struct Node *next; }Node; Node *head = NULL; Node *getLast(Node *head); void queue(Node **head, Node *object); void print(Node *head); int countNodes(Node *head); void check(Node *head); Node *getNth(Node *head, int n); void delNth(Node **head, int n); void popHead(Node **head); void delOdds(Node *head); int main(void) { FILE *fp; if ((fp = fopen("suka.blyad", "wb")) == NULL) { return 69; } smallNode array[5]; int j; for (j = 0; j < 5; j++) { array[j].val = j; } strcpy(array[0].str, "zero"); strcpy(array[1].str, "one"); strcpy(array[2].str, "two"); strcpy(array[3].str, "three"); strcpy(array[4].str, "four"); int i; smallNode *object0 = (smallNode *)malloc(sizeof(smallNode)); for (i = 0; i <5; i++) { *object0 = array[i]; if (fwrite(object0, sizeof(smallNode), 1, fp) != 1) { puts("IO error."); exit(-3); } } fclose(fp); if ((fp = fopen("suka.blyad", "rb")) == NULL) { return 4; } Node * object = (Node *)malloc(sizeof(Node)); while (1) { if (fread(object0, sizeof(smallNode), 1, fp) != 1) { break; } object->smallNode = *object0; queue(&head, object); } print(head); puts("After deleting odds: "); delOdds(head); print(head); return 0; } void check(Node *head){ //function to check if the list exists if(head == NULL){ puts("NaL"); exit(-1); } } Node *getLast(Node *head) { if (head == NULL) { return NULL; } while (head->next) { head = head->next; } return head; } void queue(Node **head, Node *object) { Node *tmp = (Node *)malloc(sizeof(Node)); Node *last = getLast((*head)); *tmp = *object; tmp->next = NULL; if (last != NULL) { last->next = tmp; } else { *(head) = tmp;; } } void print(Node *head) { if (head == NULL) { puts("NaL"); exit(-4); } int c = 0; while (1) { printf("Node: %d.\n", ++c); puts("-----------------------------------------"); printf("|Int: %6d | String: %7s %3c\n", head->smallNode.val, head->smallNode.str, '|'); puts("-----------------------------------------"); if (head->next!=NULL) { head = head->next; } else { break; } } } int countNodes(Node *head){ //use this function to check out of bounds check(head); int count = 0; while(1){ count++; if(head->next){ head = head->next; } else{ return count; } } } Node *getNth(Node *head, int n){ check(head); if(n > countNodes(head) || n < 0){ puts("Out of bounds."); exit(-5); } int i; for(i = 0; i < n-1; i++){ head = head->next; } return head; } void delNth(Node **head, int n){ //cant delete the first node check((*head)); Node *prev = getNth((*head), n-1); Node *elm = prev->next; prev->next = elm -> next; free(elm); } void popHead(Node **head){ //can only delete the first node, called only if n == 1 check((*head)); Node *elm = (*head); (*head) = (*head)->next; free(elm); } void delOdds(Node *head){ //function to go throught the list, check for odds and call the functions doing the deletion check(head); int n = 0; while(1){ ++n; if(head->smallNode.val % 2){ if(n == 1){ popHead(&head); } else{ delNth(&head, n); } } if(head->next){ head = head->next; } else{ print(head); break; } } } 指针,但是它是从文件写入和读取的对象。它与smallNode相对应。

next是组成列表的对象,它也是传递给object0函数的对象,该函数创建列表。

1 个答案:

答案 0 :(得分:1)

看到崩溃是因为您在每次迭代中都增加了本地Head Dictionary.GetValueOrDefault,并且将相同的本地Head传递给了head = head->next;,后者使用delNth()函数来获取第N个节点。由于您的getNth()函数从列表的开头开始计数并返回第N个节点,因此最终指向无效地址。

如果要继续使用自己的方法,则需要进行以下更改。

  1. 维护本地指针以遍历列表。
  2. getNth()更改为delNth(Node **head, int n)以避免 更改Head节点。
  3. 在删除时传递实际的头像。
  4. 删除delNth(Node *head, int n)的减量后,您的节点数和n保持不变。

以下是修改后的代码。

n

我建议您采用以下方法。

void delOdds(Node *head){ 
        check(head);
        Node *localHead = head;
        int n = 0;
        while(1){
       printf("processing node=%d n=%d\n", localHead->smallNode.val, n);
            ++n;
            if(localHead->smallNode.val % 2){
                if(n == 1){
                    popHead(&head);
                }
                else{
                    delNth(head, n);
                    n--;
                }
            }
            if(localHead->next){
                localHead = localHead->next;
            }
            else{
                print(localHead);
                break;
            }
        }
    }