[英]C segmentation fault when I try to dequeue
我正在制作服务器客户端程序。
客户端的收集器需要将数据包数据入队,发送方需要将它们出列。
每当我尝试使数据包出队时,都会出现分段错误。
这是整个队列实现:
aqueue *init_aqueue(void)
{
aqueue *q;
q = malloc(sizeof(aqueue));
q->head = NULL;
q->tail = NULL;
return (q);
}
aqueue_node *init_node(packet *data, aqueue_node *tail)
{
aqueue_node *new;
new = malloc(sizeof(aqueue_node));
new->data = data;
new->prev = tail;
new->next = NULL;
}
packet *peek(aqueue *q)
{
packet *res;
if (!q->size)
return (NULL);
else
{
res = malloc(sizeof(packet));
res->length = q->head->data->length;
res->payload = strndup(q->head->data->payload, res->length);
}
return (res);
}
void enqueue (aqueue *q, packet *data)
{
aqueue_node *new;
new = init_node(data, q->tail);
if (q->head == NULL) //adding first node of aqueue
{
q->head = new;
q->size = 1;
}
else
{
q->tail->next = new;
q->size += 1;
}
q->tail = new;
}
packet *dequeue(aqueue *q)
{
packet *data;
aqueue_node *temp;
if (q->size == 0)
{
return (NULL);
}
else
{
if (q->head == q->tail)
{
//When aqueue contains only one node
free(q->head->data);
free(q->head);
q->tail = NULL;
q->head = NULL;
}
else
{
data = peek(q);
temp = q->head;
q->head = q->head->next;
q->head->prev = NULL;
free(temp->data);
free(temp);
}
q->size--;
return (data);
}
}
然后我将其作为 agent.c 文件中的共享资源:
aqueue * queue;
采集器代码:
//send four packet
pthread_mutex_lock(&p->aqueue_lock);
enqueue(q, get_mem_info());
enqueue(q, get_net_info());
enqueue(q, get_cpu_info());
enqueue(q, get_proc_info());
发件人代码:
packet *data;
data = NULL;
if (q->size > 0)
{
data = dequeue(q);
}
if (data)
{
if (0 > send(clientfd, data->payload, data->length,
{
perror("send error");
exit (EXIT_FAILURE);
}
}
lldb 结果:
* thread #2, name = 'agent', stop reason = signal SIGSEGV: invalid address (fault address: 0x50e8)
frame #0: 0x0000aaaaaaaa3c64 agent`dequeue(q=0x0000aaaaaaab62e0) at agent_queue.c:85:18
82 {
83 cur = q->head;
84 q->head = q->head->next;
-> 85 q->head->prev = NULL;
86 free(cur->data);
87 free(cur);
88 }
编辑:
我傻了。 我修复了 init_node 以返回值:
aqueue_node *init_node(packet *data, aqueue_node *tail)
{
aqueue_node *new;
new = malloc(sizeof(aqueue_node));
new->data = data;
new->prev = tail;
new->next = NULL;
return (new); //added
}
但我仍然遇到同样的错误..
dequeue 的返回数据与 dequeue 内部的释放数据不同。 我更改了变量名称以使其清楚:
packet *dequeue(aqueue *q)
{
packet *copied_data;
aqueue_node *temp;
printf("queue size : %d\n", q->size);
if (q->size == 0)
{
return (NULL);
}
else
{
if (q->head == q->tail)
{
//When aqueue contains only one node
free(q->head->data);
free(q->head);
q->tail = NULL;
q->head = NULL;
}
else
{
copied_data = peek(q);
temp = q->head;
q->head = q->head->next;
q->head->prev = NULL;
free(temp->data);
free(temp);
}
q->size--;
return (copied_data);
}
}
我发现我没有在队列 function 中正确分配 prev。 但仍然发生同样的错误
void enqueue (aqueue *q, packet *data)
{
aqueue_node *new;
new = init_node(data, q->tail);
if (q->head == NULL) //adding first node of aqueue
{
q->head = new;
q->size = 1;
}
else
{
q->tail->next = new;
new->prev = q->tail; //added
q->size += 1;
}
q->tail = new;
}
编辑:
我在收集后释放了整个队列以进行调试并且错过了擦除它。 这就是问题所在。 很抱歉造成混淆
启用并注意编译器的警告!!! (我使用-Wall -Wextra -pedantic
和 gcc。)它会发现问题。
init_node
不返回值。 所以你不是在队列中添加一个节点,而是垃圾。 你的编译器会告诉你的。
您在dequeue
中遇到类似的问题,其中并非所有路径都在到达return data
data
设置数据。
此外,当您确实从dequeue
返回值时,它似乎是指向您已释放的 memory 的指针。 那不好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.