C语言 我的代码可以在一个编译器上工作,但不能在其他编译器上工作,

ezykj2lf  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(131)

linkedList.c

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

struct Node {
    int data;
    struct Node *next;
};

typedef struct Node *node;

node createNode(int val) {
    node newNode = (node)malloc(sizeof(struct Node));
    if (newNode == NULL) {
        printf("cannot allocate memory");
        exit(EXIT_FAILURE);
    }
    newNode->data = val;
    newNode->next = NULL;
    return newNode;
}

node insertFront(node head, int val) {
    node insert = createNode(val);
    if (head == NULL) {
        head = insert;
        return head;
    }
    insert->next = head;
    head = insert;
    return head;
}

node insertTail(node head, int val) {
    node insert = createNode(val);
    node temp = head;
    if (head == NULL) {
        head = insert;
        return head;
    }
    while (temp->next != NULL)
        temp = temp->next;
    temp->next = insert;
    insert->next = NULL;
    return head;
}

node listSearch(node head, int val) {
    node temp = head;
    while (temp != NULL) {
        if (temp->data == val) {
            printf("%d\n", 1);
            return temp;
        }
        temp = temp->next;
    }
    printf("%d\n", -1);
    return NULL;
}

node insertAfter(node head, int afterThisVal, int val) {
    node afterThis = listSearch(head, afterThisVal);
    if (afterThis == NULL)
        return head;
    if (afterThis->next == NULL) {
        head = insertTail(head, val);
        return head;
    }
    node insert = createNode(val);
    node temp = afterThis->next;
    afterThis->next = insert;
    insert->next = temp;
    return head;
}

node insertBefore(node head, int beforeThisVal, int val) {
    node beforeThis = listSearch(head, beforeThisVal);
    if (beforeThis == NULL)
        return head;
    if (beforeThis == head) {
        head = insertFront(head, val);
        return head;
    }
    
    node prev = head;
    while (prev->next != beforeThis)
        prev = prev->next;

    node insert = createNode(val);
    prev->next = insert;
    insert->next = beforeThis;
    return head;
}

node deleteFirst(node head) {
    if (head == NULL) {
        printf("%d\n", -1);
        return head;
    }
    node temp = head;
    head = head->next;
    printf("%d\n", temp->data);
    free(temp);
    return head;
}

node deleteLast(node head) {
    if (head == NULL) { 
        printf("%d\n", -1);
        return head;
    }
    node temp = head;
    node prev = NULL;
    while (temp->next != NULL) {
        prev = temp;
        temp = temp->next;
    }
    if (prev != NULL)
        prev->next = NULL;
    printf("%d\n", temp->data);
    free(temp);
    return head;
}

node deleteNode(node head, int val) {
    node found = listSearch(head, val);
    if (found == NULL) {
        printf("%d\n",-1);
        return head;
    }
    else if (found == head) {
        head = deleteFirst(head);
        return head;
    }
    else if (found->next == NULL) {
        head = deleteLast(head);
        return head;
    }
    node prev = head;
    while (prev->next != found)
        prev = prev->next;
    prev->next = found->next;
    printf("%d\n", found->data);
    free(found);
    return head;
}

void display(node head) {
    if (head == NULL)
        return;
    node temp = head;
    while (temp->next != NULL) {
        printf("%d ", temp->data);
        temp = temp->next;
    }
    printf("%d\n", temp->data);
}

node reverseList(node head) {
    node i = head;
    node j = NULL;
    node k = NULL;

    while (i != NULL) {
        k = j;
        j = i;
        i = i->next;
        j->next = k;
    }
    return j;
}

node reverseEven(node head) {
    node oddHead = head;
    node odd = head;
    node evenHead = head->next;
    node even = head->next;
    node temp1 = NULL;
    node temp2 = NULL;
    while (odd->next != NULL && even->next != NULL) {
        odd->next = even->next;
        odd = odd->next;
        even->next = odd->next;
        even = even->next;
    }
    if ((odd != NULL && odd->next != NULL) || (even != NULL && even->next != NULL)) {
        odd->next = NULL;
        even->next = NULL;
    }
    display(evenHead);
    display(oddHead);
    evenHead = reverseList(evenHead);
    even = evenHead;
    odd = oddHead;
    while (even != NULL && odd != NULL) {
        temp1 = odd;
        odd = odd->next;
        temp1->next = even;
        temp2 = even;
        even = even->next;
        temp2->next = odd;
    }
    return head;
}

int main() {
    char op[2];
    node head = NULL;
    int inp1, inp2;
    scanf("%s", op);
    while (strcmp(op, "e") != 0) {
        if (strcmp(op, "f") == 0) {
            scanf("%d", &inp1);
            head = insertFront(head, inp1);
            display(head);
        }
        else if (strcmp(op, "t") == 0) {
            scanf("%d", &inp1);
            head = insertTail(head, inp1);
            display(head);
        }
        else if (strcmp(op, "a") == 0) {
            scanf("%d", &inp1);
            scanf("%d", &inp2);
            head = insertAfter(head, inp2, inp1);
            display(head);
        }
        else if (strcmp(op, "b") == 0) {
            scanf("%d", &inp1);
            scanf("%d", &inp2);
            head = insertBefore(head, inp2, inp1);
            display(head);
        }
        else if (strcmp(op, "d") == 0) {
            scanf("%d", &inp1);
            head = deleteNode(head, inp1);
            display(head);
        }
        else if (strcmp(op, "i") == 0) {
            head = deleteFirst(head);
            display(head);
        }
        else if (strcmp(op, "l") == 0 ){
            head = deleteLast(head);
            display(head);
        }
        else if (strcmp(op, "s") == 0) {
            scanf("%d", &inp1);
            listSearch(head, inp1);
        }
        else if (strcmp(op, "r") == 0) {
            head = reverseList(head);
        }
        else if (strcmp(op, "ds") == 0) {
            display(head);
        }
        else if (strcmp(op, "re") == 0) {
            head = reverseEven(head);
        }
        else {
            printf("INVALID\n");
        }
        scanf("%s", op);
    }
    return 1;
}

我的代码实现了链表的所有功能作为一个菜单驱动的程序。

input.txt

f 7
t 10
a 11 7
b 12 11
d 10
i
l
s 12
s 6
t 15
f 14
f 20
ds
r
re
e

我看到的错误是分段错误。在input.txtf 20之后的ds(显示函数),head随机获得一个垃圾值,并显示mingw_ovr _bulletin_va_lists部分我不确定我犯了什么错误。
请原谅我在代码中使用的不好的做法,因为我还在学习C。

nhjlsmyf

nhjlsmyf1#

函数deleteLast中有一个bug:你必须测试head是否已经是最后一个节点,并在释放temp后返回NULL。当你在这之后从head读取时,你有未定义的行为,因为你解引用了一个无效的指针。未定义的行为意味着任何事情都可能发生,包括不同运行或不同计算机上的不同行为。
以下是修改后的版本:

node deleteLast(node head) {
    if (head == NULL) { 
        printf("%d\n", -1);
        return head;
    }
    node temp = head;
    node prev = NULL;
    while (temp->next != NULL) {
        prev = temp;
        temp = temp->next;
    }
    if (prev == NULL) {
        head = NULL;
    } else {
        prev->next = NULL;
    }
    printf("%d\n", temp->data);
    free(temp);
    return head;
}

main中还有一个问题:将op定义为2个char的数组:这个数组只能存储一个字符串,最多一个字符和一个空字节,但是你用scanf("%s", op)从用户那里读取,所以任何超过1个字符的输入字都会导致缓冲区溢出,因为scanf()不知道目标数组有多长。
您应该使数组更长,并告诉scanf()要存储到目标数组中的最大字符数,其长度介于%s之间:

char op[20];
    node head = NULL;
    int inp1, inp2;
    if (scanf("%19s", op) != 1)
        return 1;

相关问题