JUnKe55!W 2022-05-07 13:22 采纳率: 100%
浏览 49
已结题

在用这个代码的追加结点函数添加较多的结点后就报错是什么原因?

代码比较长


#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <malloc.h>

// 构建链表抽象类型 
typedef struct Node{
    int data;
    struct Node *next;
}Node, *LinkList; 

// 生成链表数据 
int CreateListTail(LinkList &L, int n){
    int i, num = 0;
    Node *p, *r = L;
    while(r->next){
        r = r->next;
    }
    for(i = 0; i < n; i++){
        // 创建结点 
        if(!(p = (Node*)malloc(sizeof(Node*)))){
            printf("链表结点创建失败\n");
            return 0;
        }
        // 给结点随机赋值 
        p->data = rand()%100+1;
        r->next = p;
        r = r->next;
        num++;
    }
    printf("成功添加了%d个结点\n", num);
    p->next = NULL;
}

// 结点个数 
int ComList(LinkList &L){
    if(L->next == NULL){
        printf("Sum Node Error 这是一个空链表\n");
        return 0;
    }
    int sum = 0;
    Node *p = L; 
    while(p->next){
        p = p->next;
        printf("%d,", p->data);
        sum++;
    }
    printf("\n");
    return sum;
}

// 查找结点
int FindNode(LinkList &L, int i, int* e){
    if(L->next == NULL){
        printf("Find Node Error 这是一个空链表\n");
        return 0;
    }
    Node *p = L;
    int j = 0;
    while(p && j < i){ 
        p = p->next;
        j++;
    }
    if(!p || j > i){ 
        printf("FIND ERROR\n");
        return 0;
    }
    *e = p->data;
    printf("第%d个结点的值为%d\n", i, *e);
}
 
// 查找结点(值)
int FindValue(LinkList &L, int v){
    if(L->next == NULL){
        printf("Find Value Error 这是一个空链表\n");
        return 0;
    }
    int n = 1;
    Node *p = L->next;
    while(p){
        if(p->data == v){
            printf("p->data=%d,v=%d\n", p->data, v);
            printf("该值在第%d结点\n", n);
            return n;    
        }
        p = p->next;
        n++;
    }
    printf("没有找到该值\n");
    n = NULL;
    return 0;
} 

// 插入结点
int InsertNode(LinkList &L, int i, int e){
    Node *p, *n;
    int j = 0;
    p = L;
    while(p && j < i-1){ 
        j++;
        p = p->next;
    }
    if(!p || j > i-1){
        printf("Inser ERROR\n");
        return 0;
    }
    if(!(n = (Node*)malloc(sizeof(Node)))){
        printf("结点创建失败\n");
        return 0;
    }
    n->data = e;
    n->next = p->next;
    p->next = n;
} 

// 删除结点 
int DeleteNode(LinkList &L, int i, int *e){
    if(L->next == NULL){
        printf("Delete Node Error 这是一个空链表\n");
        return 0;
    }
    Node *p, *n;
    int j = 0, n1 = 0;
    p = L;
    while(p->next && j < i-1){ 
        p = p->next;
        j++;
        printf("n=%d\n", ++n1);
    }
    if(!(p->next) || j > i-1){ 
        printf("Delete ERROR\n");
        return 0;
    }
    n = p->next;
    *e = n->data;
    p->next = n->next;
    free(n);
    n = NULL;
}

// 销毁链表 
int DistroyList(LinkList &L){
    if(L->next == NULL){
        printf("这是一个空链表");
        free(L);
        printf("共销毁了1个结点(包括头结点 )\n");
        return 0;
    }
    Node *p, *t;
    int sum = 0;
    p = L;
    while(p){
        t = p->next;
        free(p);
        p = t;
        sum++; // 包括头结点 
    }
    printf("共销毁了%d个结点(包括头结点 )\n", sum);
}

// 清空链表(保留头结点)
int ClearList(LinkList &L){ 
    Node *p = L->next, *r;
    while(p){
        r = p->next;
        free(p);
        p = r; // 在销毁最后一个结点后 r先指向NULL然后p也指向NULL 然后就退出循环 
    }
    L->next = NULL;
    return 0; 
} 

// 初始化链表
int InitList(LinkList &L){
    if(!(L = (Node*)malloc(sizeof(Node*)))){
        printf("链表创建失败\n");
        return 0;
    }
    // 创建头结点 
    L->next = NULL;
    L->data = 0;
} 

// 打印菜单 
 void Menu(void){
     printf(" 欢迎来到链表模拟系统:\n");
     printf("    1.显示所有结点\n    2.插入一个结点\n    3.删除一个结点\n    4.清空链表\n    5.销毁链表\n    6.按结点位置查找\n    7.按结点数值查找\n    8.查看结点数量\n    9.追加随机数\n    0.退出\n ");
     printf(" 请输入要操作的选项:\n");
 }
 
// 逻辑处理 
void Select(LinkList &L, char ch){
     int len, loc, num;
     switch(ch){
        case '0':exit(0);break;
        case '1':ComList(L);break;
        case '2':
        printf("请输入要插入的位置:\n");
        scanf("%d", &loc);
        printf("请输入要插入的值:\n");
        scanf("%d", &num);
        InsertNode(L, loc, num);
        break;
        case '3':
        printf("请输入要删除的位置:\n");
        scanf("%d", &loc);
        DeleteNode(L, loc, &num);
        break;
        case '4':
        ClearList(L); 
        printf("列表已经清空..\n"); 
        break;
        case '5':
        DistroyList(L);
        printf("列表已经摧毁..\n");
        break;
        case '6':
        printf("请输入要查找的位置\n");
        scanf("%d", &loc);
        FindNode(L, loc, &num); 
        break;
        case '7':
        printf("请输入要查找的值\n");
        scanf("%d", &num);
        FindValue(L, num);
        break;
        case '8':
        len = ComList(L);
        printf("当前链表的长度为%d\n", len);
        break;
        case '9':
        printf("请输入要追加的随机数个数:\n");
        scanf("%d", &num); 
        CreateListTail(L, num);
        break;
        default: printf("ERROR..");
    }
    printf("按任意键继续..\n\n");
    getch();
 } 
int main(void){
    LinkList L;
    int sum, n, d, f;
    char ch;
    srand(time(NULL));
    InitList(L); 
    do{
        Menu();
        ch = getch();
        Select(L, ch);
        system("cls");
    } while(ch != '0');
    return 0;
}

img

用CreateListTail追加数量比较多的结点后再调用ClearList函数然后程序就自己结束了

img

如果追加的数量的小一点的话程序就可以继续

img

img

这是什么原因呢?

  • 写回答

1条回答 默认 最新

  • 我秃了,但没强 2022-05-07 14:29
    关注

    创建节点的malloc里面,为什么是malloc(sizeof(Node*))?sizeof(Node*)是指针类型的大小,不是Node类型的大小,应该用sizeof(Node)吧?
    main函数返回0xc0000374(也即3221226356)的意义是堆栈崩溃,一般来说是使用了申请的内存之外的未申请的内存,在你这程序里你给每个节点申请的内存是sizeof(Node*)也即4个字节,但你实际需要使用的是sizeof(Node)这么多个字节,所以你在给新节点赋值时会使用没有申请的内存,当下次访问或者释放这部分内存时或者程序结束时就触发堆栈溢出崩溃。
    参考链接:https://blog.csdn.net/chunyexiyu/article/details/120233683

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 5月15日
  • 已采纳回答 5月7日
  • 创建了问题 5月7日

悬赏问题

  • ¥15 python的qt5界面
  • ¥15 无线电能传输系统MATLAB仿真问题
  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100