You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C99队列初始化函数触发Segmentation Fault的原因排查

循环队列初始化段错误的定位与修复

你的核心问题是没有为queue_t结构体本身分配内存。在create_queue函数里,你把q初始化为NULL后直接访问q->len、q->vals等成员——这属于对空指针的非法解引用,正是触发Segmentation Fault和Valgrind报错的原因。

从结构体布局来看,len成员相对于queue_t起始地址的偏移量是16字节(0x10),当q为NULL时,q->len等价于访问地址0 + 0x10 = 0x10,完全匹配Valgrind报错的无效内存地址。

修复后的代码

修复时需要先为结构体本身分配内存,再初始化成员,同时要检查内存分配是否成功,避免泄漏:

/* Queue structure which holds all necessary data */
typedef struct queue {
    int head;
    int tail;
    void** vals;
    int len;
    int count;
} queue_t;

/* creates a new queue with a given size */
queue_t* create_queue(int capacity){
    // 先为queue_t结构体分配内存
    queue_t* q = malloc(sizeof(queue_t));
    if (q == NULL) {
        return NULL;
    }
    q->len = capacity;
    // 为存储元素的指针数组分配内存
    q->vals = malloc(sizeof(void*) * q->len);
    if (q->vals == NULL) {
        // 若vals分配失败,释放已分配的结构体内存,避免泄漏
        free(q);
        return NULL;
    }
    q->head = 0;
    q->tail = 0;
    q->count = 0;
    return q;
}

后续动态扩容的注意点

实现动态扩容时需要留意:

  • 重新分配更大的void**数组,拷贝原数组元素(循环队列元素可能头尾环绕,需分两段拷贝)
  • 更新len为新容量,释放旧的vals数组
  • 调整head和tail的索引位置,确保队列逻辑正确

内容的提问来源于stack exchange,提问作者Jakub Novák

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 17:58:11