繁体   English   中英

C 尝试出队时出现分段错误

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM