运行时引发了异常: 读取访问权限冲突。p2 是 0xF

要写一个职工工资管理系统;

1. 职工工资项目信息的基本结构如下:
char *ITEM[MAXI] //职工工资项目数组,存放工资项目名称。(字符串数组)
说明:工资项目可包括:基本工资、职务工资、岗位津贴、医疗保险、公积金、
奖金、住房补贴等。工资项目可以按需要增加、修改和删除,不固定。工资项目
最多 50 项, 0~49。
2.系统基本功能:提供工资项目信息的录入、修改和删除;职工工资信息的录
入、修改、查询和统计等,工资项目及职工工资信息可保存在文件中,系统启动
时打开文件可新增职工工资信息并保存。

结构体:

typedef struct staff {
    int num;            /* 职工编号 */
    char name[20];        /* 姓名 */
    char dept[50];        /* 所属部门 */
    double S[MAXI];         /* 工资项目数组,与数组 ITEM[MAXI]的标号对应,0~49*/
    double total;        /* 工资合计 */
    struct stuff *next;
}EMPLOYEE;

主函数中全局变量:

EMPLOYEE* head = NULL, * tail = NULL;
char ITEM[MAXI][20];
int count1 = -1;        /*项目数量计数*/ /*count1 +1 是真实的项目数量*/
int count_staffnum = 0;        /*职工数量统计*/

相关函数:

extern EMPLOYEE* head;
void fun12()    /*删除职工信息记录*/
{
    EMPLOYEE* p1=NULL, * p2=NULL;
    int num;
    char re[10];
    int cnt=0;    //用于计数
    if (head == NULL)
    {
        printf("\n");
        printf("职工信息记录为空,无法删除\n");
        printf("请按任意键返回上一级\n");
        printf(">>");
        getch(re);
    }
    else
    {
        printf("\n");
        printf("请输入想要删除的职工编号,按回车结束\n");
        printf("返回上一级请输入0\n");
        printf(">>");
        scanf("%d", &num);

        p1 = (EMPLOYEE*)malloc(sizeof(EMPLOYEE));
        p2 = (EMPLOYEE*)malloc(sizeof(EMPLOYEE));
        p1 = head;
        while (p1 != NULL)
        {
            if (p1->num == num)
            {
                cnt++;
                break;
            }
            p1 = p1->next;
        }
        if (cnt == 0)
        {
            printf("查无此员工,无法删除\n");
            printf("请按任意键返回上一级\n");
            printf(">>");
            getch(re);
        }

        if (num != 0)
        {
            p1 = head;
            p2 = p1->next;
            while (p2 != NULL)
            {
                if (p2->num==num)
                {
                    p1->next = p2->next;
                    free(p2);
                    p2 = p1->next;
                }
                else
                {
                    p1 = p1->next;
                    p2 = p2->next;
                }
            }
            if (head->num == num)
            {
                p2 = head;
                head = p2->next;
                free(p2);
            }
            printf("删除职工信息成功!\n");
            printf("请按任意键返回上一级\n");
            printf(">>");
            getch(re);
        }
    }
}

建立链表用于储存职工的ID、姓名、部门、工资项目等;
我已经新增了一个职工信息记录,想要删除:

img

但运行遇到了这个问题:

img


显示引发了异常: 读取访问权限冲突。p2 是 0xF(很多个F)。

请问怎么解决?

删除函数修改如下,供参考:

extern EMPLOYEE* head;
void fun12()    /*删除职工信息记录*/
{
    EMPLOYEE* p1=NULL, * p2=NULL;
    int num;
    char re[10];
    int cnt=0;    //用于计数
    if (head == NULL)
    {
        printf("\n");
        printf("职工信息记录为空,无法删除\n");
    }
    else
    {
        printf("\n");
        printf("请输入想要删除的职工编号,按回车结束\n");
        printf("返回上一级请输入0\n");
        printf(">>");
        scanf("%d", &num);

        if (num != 0)
        {
            p1 = head; p2 = NULL;
            while (p1)
            {
                if (p1->num == num)
                {
                    cnt++;
                    break;
                }
                p2 = p1;
                p1 = p1->next;
            }
            if (cnt == 0)
                printf("查无此员工\n");
            else{
                if (p2 == NULL)
                {
                    p2 = head;
                    head = p2->next;
                    free(p2);
                }
                else{
                    p2->next = p1->next;
                    free(p1);
                }
                printf("删除职工信息成功!\n");
            }
        }
    }
    printf("请按任意键返回上一级\n");
    printf(">>");
    getch(re);
}