我在C中有以下代码,试图开发操作系统模拟:
Queue.c:
typedef enum {running,readyproc,waiting,suspended}status;
typedef struct pcb {
long pid;
char* pname;
long priority;
long sleepperiod;
long* context;
status stat;
}PCB;
typedef enum {ready, timer, suspend} queuetype;
typedef struct {
int size;
int capacity;
PCB ** data;
queuetype qt;
}Queue;
void queue_init(Queue *q, queuetype qt){
q->size =0;
q->capacity = QUEUE_INITIAL_CAPACITY ;//100
q->data = (PCB **)calloc(q->capacity,sizeof(PCB*));
q->qt = qt;
}
PCB* queue_pop (Queue* q){
PCB* toReturn;
int i;
toReturn = q->data[0];
for (i=0;i<q->size;i++){
q->data[i]=q->data [i+1];
}
free(q->data[q->size]);
q->size--;
printf ("toReturn id:%ld pname: %s\n", toReturn->pid, toReturn->pname);
return toReturn;
}
知道队列被初始化并填充了PCB。我总是在打电话时遇到一个问题:
PCB* pcb = queue_pop(&queue);
编辑: 这是填充队列的函数:
void queue_append(Queue *q, PCB* value)
{
q->data[q->size++] = value;
}
EDIT2:
在queue_pop
返回之前的printf返回:
toReturn id: 2 pname: test1c_a
对应于我想从该队列中弹出的内容。
答案 0 :(得分:2)
for (i=0;i<q->size;i++){
q->data[i]=q->data [i+1];
}
如果q->size == q->capacity
,那么您将在q->data
的末尾运行(它将访问q->data[q->capacity]
,这是超过其分配长度的一个。)
P.S。有更有效的方法可以做到这一点。
答案 1 :(得分:0)
以下似乎是一个问题。
free(q->data[q->size]);
假设两个元素在队列q->size = 2
中由
q->data[0]
和q->data[1]
所以当queue_pop调用时。上面的代码将免费q->data[2]
。这可能会导致seg-fault。