Newhere2 2022-11-06 20:46 采纳率: 0%
浏览 107
已结题

队列问题:读取访问权限冲突,X 是 nullptr(语言-c++)

发生如图错误,已知到错误原因,求解决方案

img

#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<math.h>
using namespace std;
#define MAXSIZE 5
#define INF 100

typedef struct servedtime1 {
    int front;
    int rear;
    double data[MAXSIZE];
} servedtime1;


servedtime1* initservedtime1() {
    servedtime1* X = (servedtime1*)malloc(sizeof(servedtime1));
    X->front = X->rear = 0;
    return 0;
}//初始化队列

servedtime1* X;


int isFull(servedtime1* X) {
    if ((X->rear + 1) % MAXSIZE == X->front) {
        return 1;
    }
    else {
        return 0;
    }
}//判断队列是否满

int isEmpty(servedtime1* X) {
    if (X->front == X->rear) {
        return 1;
    }
    else {
        return 0;
    }
}//判断队列是否为空

int enservedtime1(servedtime1* X, double  data) {
    if (isFull(X)) {
        return 0;
    }
    else
    {
        X->data[X->rear] = data;
        X->rear = (X->rear + 1) % MAXSIZE;
        return 1;
    }
}//入列

double deservedtime1(servedtime1* X) {
    if (isEmpty(X)) {
        return -1;
    }
    else {
        double data = X->data[X->front];
        X->front = (X->front + 1) % MAXSIZE;
        return  data;
    }
}//出列


typedef struct Job {
    char name;
    double arrive;
    double serve;
    double start;
    double finish;
    struct Job* next;
}JobSL;

typedef struct S {
    int value;
    JobSL* waitingjobs;
};

S mutex;
void init()
{
    mutex.value = 0;
    mutex.waitingjobs = (JobSL*)malloc(sizeof(Job));
    mutex.waitingjobs->next = NULL;
};

//为了测试输出队列
void print(JobSL* head)
{
    JobSL* p = head->next;
    cout << "当前队列:";
    while (p != NULL)
    {
        cout << p->name;
        p = p->next;
    }
    cout << endl;
}
//插入函数

void Insert(JobSL* head, double stime, char name)
{
    JobSL* p, * q, * r;
    p = head->next;//p为首元素  p用来遍历无序部分的元素
    q = head;    //p为头节点 
    while (p != NULL) {
        //if (p->price == price) {//已存在就增加数量
        //    p->count += count;
        //    return;
        //}
        if (p->serve >= stime) {//找到合适的插入位置
            r = (JobSL*)malloc(sizeof(struct Job));
            r->serve = stime;
            r->name = name;
            r->next = q->next;//把r插入到
            q->next = r;    //q的后面
            cout << "当前任务入队完成" << endl;
            print(head);
            return;
        }
        else if (p->serve < stime) {
            q = p;//q始终指向p的前驱
            p = p->next;
        }
    }
    //走到这里说明,表中没有比要插入的price还要大的结点
    //直接接在链表表尾就行
    r = (JobSL*)malloc(sizeof(struct Job));
    r->serve = stime;
    r->name = name;
    r->next = NULL;
    q->next = r;
    cout << "当前任务入队完成" << endl;
    print(head);
    return;
}
void Insert2(JobSL* head, double stime, char name)
{
    JobSL* p, * q, * r;
    p = head->next;//p为首元素  p用来遍历无序部分的元素
    q = head;    //p为头节点 
    while (p != NULL) {
        q = p;//q始终指向p的前驱
        p = p->next;
    }
    //走到这里说明,表中没有比要插入的price还要大的结点
    //直接接在链表表尾就行

    r = (JobSL*)malloc(sizeof(struct Job));
    r->serve = stime;
    r->name = name;
    r->next = NULL;
    q->next = r;
    cout << "当前任务入队完成" << endl;
    print(head);
    return;
}

//因为处理机一次只能处理一个任务,即需要一个互斥信号量mutex(value=0)(原理参考P53-55)
//数据结构为改进后的记录型信号量(原始记录型信号量可以直接用于先进先出,但是短优先不行,需要改进)
//------------------------------------------------------------------------------------------------------------------------------------------------

//------------------------------------------------------------------------------------------------------------------------------------------------

void wait(JobSL* applier) {    //applier表示申请的这个新作业,有新作业后台队列就需要重新排序

    if (mutex.value < 0 && applier != NULL) {  //-----------旧任务未结束,新任务到达,当前cpu正在被使用, 
        cout << "CPU被占用" << endl;
        Insert(mutex.waitingjobs, applier->serve, applier->name);    //申请任务的服务时间和名字写道队列里    
    }
    else if (mutex.value < 0 && applier == NULL) {  //---------旧任务正在执行
        //block(S->list)
        cout << "阻塞等待队列" << endl;
    }
    else {  //---------------------旧任务已结束,没有新任务到达 ,当前cpu空闲 
        mutex.value--;//此处如果不是全局变量跳出这个函数之后s的value就又回到0了
        cout << "当前任务申请到了资源" << endl;
        //tempjob=applier;   //可能有空队列,需要在后面判断  
    }
}
servedtime1* sort(servedtime1* X) {
    if ((X->rear - X->front + MAXSIZE) % MAXSIZE != 0) {
        servedtime1* X = initservedtime1();
        int N;
        N = (X->rear - X->front + MAXSIZE) % MAXSIZE;
        double buffer;
        double min;

        for (int i = 0; i < N; i++) {

            min = INF;

            for (int j = i; j < N; j++) {
                buffer = deservedtime1(X);
                if (buffer < min) {
                    if (min != INF) enservedtime1(X, min);
                    min = buffer;
                }
                else {
                    enservedtime1(X, buffer);
                }
            }
            enservedtime1(X, min);
        }
    }
    return X;
    //else {
    //    enservedtime1(X, 1);
    //}
}
void wait2(double applierserv) {
    //队列有元素
    enservedtime1(X, applierserv);
    X = sort(X);
    //队列无元素
    enservedtime1(X, applierserv);
}


JobSL* signal() {
    mutex.value++;
    if (mutex.value == 0) {
        //-----------------------当前时间等待队列空?-----------------------------------------// 
        if (mutex.waitingjobs->next == NULL) {
            cout << "此时等待队列空" << endl;
            return NULL;
        }
        else {
            cout << "唤醒等待队列" << endl;
            print(mutex.waitingjobs);
            //取出这个元素后就删除这个元素被删除节点是第一个节点:只需使head指向第二个节点即可
            JobSL* formeset = mutex.waitingjobs->next;//(一开始是头指针)指针后移,取出队头
            //mutex.waitingjobs->next = formeset->next;
            //free(formeset);//这里不能释放空间,释放了就找不到了            
            return  formeset;
        }

    }
}



JobSL* getend(JobSL* head)
{
    JobSL* p = head->next;
    while (p->next == NULL) {
        p = p->next;
        return  p;
    }


}//获取尾节点

int circle(JobSL* head) {
    JobSL* temNode;
    JobSL* endNode;
    endNode = getend(head);
    temNode = head->next;
    endNode->next = temNode;
    head->next = temNode->next;
    temNode->next = NULL;
    return 1;
}


void con() {
    wait(NULL);
}
double servedtime = 0;
int finishedjob = 0;
JobSL* tempjob = (JobSL*)malloc(sizeof(struct Job));

void Sjf(double clock, Job  allj[], int n) {
    double timespice = 0.5;
    double servedtime = 0;
    //------------------------------------------先判断当前时间是到达时间吗---------------------------------//  
    int i = 0;
    for (; i < n; i++) {
        if (allj[i].arrive == clock) {
            JobSL* applier = (JobSL*)malloc(sizeof(struct Job));/*2.结构体指针需要初始化*/
            applier->name = allj[i].name;
            applier->arrive = allj[i].arrive;
            applier->serve = allj[i].serve;

            if (mutex.value == 0) {//表示此时没有任务(第一次申请时可能cpu被征用也可能空闲)
                tempjob = applier;
            }
            cout << allj[i].name << "任务已到达\t";
            wait(applier);//如果上一个任务刚结束,下一个任务就到达,这里还申请不到资源,入队
            wait2(allj[i].serve);
            break;
        }
    }

    //-----------------------------------当前时间有正在处理的任务吗?------------------------------------// 
    //-----------------------------------当前任务结束了吗?-------------------------------------------// 
    servedtime = deservedtime1(X);
    servedtime = servedtime + timespice;
    double remainserv = tempjob->serve - servedtime;
    cout << "作业" << tempjob->name << "未结束\t";
    cout << "作业" << tempjob->name << "已处理了" << servedtime << endl;
    if (servedtime >= tempjob->serve) {
        //----------------------------------当前时间旧任务结束的瞬间?--------------------------------------------------------------------// 
        if (mutex.value == -1) {    //当前任务结束。先把CPU释放了 ,为了防止当前任务结束后一段时间没有新任务导致多次释放 
            cout << "作业" << tempjob->name << "已结束\t";
            JobSL* nextjob = signal(); //Ⅱ这里的释放资源是当前任务执行结束后的释放,是最后一次释放,此次释放完毕当前任务应该删除
            JobSL* formeset = mutex.waitingjobs->next; //删除当前已执行完的任务(此处实际上formeset和nextjob是一个东西)
            mutex.waitingjobs->next = formeset->next;
            finishedjob++; //已经处理完的任务加一
            cout << "--------当前时刻已结束执行任务数:" << finishedjob << endl;
            if (nextjob != NULL) {    //出队的任务作为下一步要执行的任务
                tempjob = nextjob;//指针可以直接赋值不用一个一个的赋值属性
                cout << "作业" << tempjob->name << "已出队" << endl;
                print(mutex.waitingjobs);
                con();
            }
            else {
                cout << "当前时刻上一任务刚处理完,且队列为空,正在等待新任务到达……" << endl;
            }
        }
        else {//mutex.value==0 
            cout << "当前时刻,后备队列为空,且无新任务到达,cpu空闲" << endl;
        }
        return; //这种情况是任务结束从而切换到下一个任务的情况,而不是时间片结束才切换到下一个任务的情况(下面的代码),所以直接返回

    }
    if (mutex.waitingjobs->next != NULL) { //至少队列里要有一个元素才有释放cpu的必要(队列里没有元素,实际上执行一个时间片之后也要释放,但释放后又被自己占用了)
        JobSL* nextjob = signal(); //Ⅰ每执行完一个时间片都要释放cpu,这个程序在任务出队列的时候没有删除
        Insert(mutex.waitingjobs, tempjob->serve, tempjob->name);//当前这个时间片的任务处理完入队
        tempjob = nextjob;    //当前时间片结束,切换到下一个任务

    }
    enservedtime1(X, servedtime);//sfj按大小入队
    //if (mutex.waitingjobs->next!=NULL || mutex.waitingjobs->next->next != NULL) { //等待队列里至少要有两个元素才能执行交换
    //    //circle(mutex.waitingjobs); //任务等待队列做的相应操作
    //}

}

void input(int n, Job j[])
{
    for (int i = 0; i < n; i++) {
        cout << "请顺次输入①任务名称,②到达时间,③服务时间: ";
        cin >> j[i].name >> j[i].arrive >> j[i].serve;
    }
    cout << endl;
}
int main()
{
    init();
    servedtime1* X = initservedtime1();//初始化队列
    int n;
    cout << "请输入任务数量: ";
    cin >> n;
    Job j[100];
    input(n, j);
    //因为调度跟时间有关,先加一个计数器,假设这个方法返回一个整形t

    for (double clock = 0; clock <= 100; clock++)
    {
        cout << "现在时刻" << clock << "---------------------------" << endl;
        Sjf(clock, j, n);
        if (finishedjob == n)//加上当前这个已经完成了n个任务
        {
            cout << "所有任务均已处理完成--------------------------END";
            break;
        }
    }
    return 0;
}



  • 写回答

5条回答 默认 最新

  • Newhere2 2022-11-06 20:50
    关注

    最好有大佬帮我看下能怎么执行出来(我知道我是fw)

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 11月7日
  • 赞助了问题酬金15元 11月6日
  • 创建了问题 11月6日

悬赏问题

  • ¥15 react-diff-viewer组件,如何解决数据量过大卡顿问题
  • ¥20 遥感植被物候指数空间分布图制作
  • ¥15 安装了xlrd库但是import不了…
  • ¥20 Github上传代码没有contribution和activity记录
  • ¥20 SNETCracker
  • ¥15 数学建模大赛交通流量控制
  • ¥15 为什么我安装了open3d但是在调用的时候没有报错但是什么都没有发生呢
  • ¥50 paddleocr最下面一行似乎无法识别
  • ¥15 求某类社交网络数据集
  • ¥15 靶向捕获探针方法/参考文献