我正在做一些C练习(新手)我遇到了一些问题。我获得了先进先出队列并被告知将删除功能修改为FILO。
当我遗漏自由时((void *)p),这很好用;在while循环中,我从前一个方法中取出了这一行。任何人都可以告诉我为什么当这条线存在时它不起作用?我猜我不能因内存泄漏而无法将其删除?
/* remove next Item from queue, placing it in the 2nd argument;
* return 1/0 if successful/queue empty */
int q_remove(Queue *q, Item i) {
struct q_element *p;
if (q->head == NULL)
return 0;
if(q->head==q->tail){
p=q->head;
q->head=NULL;
q->tail=NULL;
memcpy(i, p->value, q->size);
free(p->value);
free((void *) p);
return 1;
}
p=q->head;
while(p != NULL){
if(p->next==q->tail){
memcpy(i, p->next->value, q->size);
free(p->next->value);
q->tail=p;
q->tail->next=NULL;
free((void *) p);
return 1;
}
p=p->next;
}
return 0;
}
答案 0 :(得分:2)
问题是你指出了你将在下一个代码行中释放的东西:
q->tail=p;
...
free((void *) p);
现在,当您尝试访问q->尾部时,您会收到错误,因为您已经释放了此内存。
你应该尝试免费p->而不是p(因为p-> next是你队列中的最后一项 - 所以这就是你要拿出的那个)
祝你好运:)答案 1 :(得分:1)
行:
q->tail->next=NULL;
free((void *) p);
......应该是
free( free( (void *) p->next );
p->next=NULL;
因为你并没有试图释放'p'(这是你的新'尾'),但是元素p->接下来是你的老尾巴。在释放它之后将指针设置为null。 q-> tail的值已经指向'p',之后释放'p'无效,因为'p-> next'就是你要删除的内容。
可能就是这样。
另外,我个人并不喜欢你如何将'Item'作为一个void *在某个地方输入,它看起来很混乱,因为'Item'看起来像是堆栈上传递的值变量。
千电子伏
答案 2 :(得分:0)
在我看来,你正在释放p
,但在你这样做之前,你将p
的值分配给q->tail
,让q->tail
指向即将成为内存无效。您实际上正在释放q->tail
。
在其他地方,我怀疑你使用q->tail
然后会让你的操作系统尖叫并像旱谷中的哈迪斯一样杀死你的程序。