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
相关产品推荐
相关产品推荐

