当我尝试出列时出现C分段错误



我正在制作服务器客户端程序。

客户端的收集器需要将数据包数据排入队列,而发送方则需要将它们排成队列。

每当我试图将数据包出列时,都会出现分段错误。

以下是整个队列实现:

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
}

但我还是犯了同样的错误。。

出队列的返回数据与出队列中释放的数据不同。我更改了变量名称以使其清楚:

packet  *dequeue(aqueue *q)
{
packet      *copied_data;
aqueue_node *temp;
printf("queue size : %dn", 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);
}
}

我发现我在入队函数中没有正确分配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返回一个值时,它似乎是一个指向您释放的内存的指针!这不好。

相关内容

  • 没有找到相关文章

最新更新