C 返回指针后出现SEGFULT
我用C编写了以下代码,试图开发一个操作系统模拟: c队:C 返回指针后出现SEGFULT,c,segmentation-fault,C,Segmentation Fault,我用C编写了以下代码,试图开发一个操作系统模拟: 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, su
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;
}
编辑:
下面是将填充队列的函数:
void queue_append(Queue *q, PCB* value)
{
q->data[q->size++] = value;
}
编辑2:
queue\u pop
中返回前的printf返回:
toReturn id: 2 pname: test1c_a
对应于我要从该队列中弹出的内容。for(I=0;isize;I++){
for (i=0;i<q->size;i++){
q->data[i]=q->data [i+1];
}
q->data[i]=q->data[i+1];
}
如果q->size==q->capacity
,那么您将运行q->data
的末尾(它将访问q->data[q->capacity]
,这是超过其分配长度的长度)
还有很多更有效的方法可以做到这一点。下面似乎是个问题
free(q->data[q->size]);
假设队列中有两个元素q->size=2
hold by
q->data[0]
和q->data[1]
所以当你打电话的时候。上述代码将释放
q->data[2]
。这可能导致seg故障。循环(修复长度错误后)是移动多个元件的好方法。明确、正确地表达意图;现代的编译器会像编写memmove
一样对其进行优化,甚至可能做得更好。(当然,以不同的方式设计数据结构,使弹出不涉及移动任何元素会更好!)这确实是我代码中的一个bug。但这并不能解决我的错误。@m-m——或者可以在数组中保留头和尾索引,完全避免移动@outvader——在您将数据
元素移过之后,是否应该将数组中的最后一项置空?否则,在空队列上调用queue\u pop
将返回垃圾。queue\u pop
永远不会在空队列上调用。我检查队列已满时,如果q->size==0
,是否q->size==q->capacity
?如果是这样,free(q->data[q->size])代码>行将访问分配数组末端以外的元素。(顺便说一句,在这里这么做似乎真的很奇怪。)请发表一篇文章。如果这太费劲了,那么至少要显示队列是如何初始化和填充的。函数queue_init
通常会初始化队列。queue_init
会使队列变空,如果在空队列上调用,则您的pop
函数会中断可能是您错误地释放了队列中的值,或任何其他问题。如果你不发布MCVE,我们就帮不了你。
free(q->data[q->size]);