实现队列入队时触发Segmentation fault的原因排查求助
队列入队函数实现的段错误排查
需求算法
需要实现基于以下算法的队列入队函数:
Algorithm: ENQUEUE (Q, ITEM) [Q is an array represent queue and ITEM is deleted item] 1. [check overflow] If Rear = MAX - 1 then a) Print: Queue is Full b) Return 2. Set Rear = Rear + 1 3. Q[Rear] = ITEM 4. Return
两种实现情况
尝试了两种实现,其中一种触发Segmentation fault错误,无法理解原因:
可运行(但存在逻辑问题)的实现
#define MAXSIZE 255 typedef struct Stack { int Q[MAXSIZE]; int rear; } Stack_t; int enqueue(int item,int(*Q)[item] ){ int rear; if (rear == sizeof(*Q)/sizeof((*Q)[0])-1){ printf("Queue is Full!"); return -1; } rear++; (*Q)[rear] = item; return rear; } int main(void){ Stack_t s = {.rear = -1}; int arr[10] = {0, 1, 2, 3, 4, 5}; int item = 2; int result; result = enqueue(item, &arr); printf("\nResult: {%i}", arr[result]); return 0; }
该代码输出:
Queue is Full! Result: {0}%
触发段错误的初始实现
int enqueue(int(*Q)[], int item, int size){ int rear; if (rear == size-1){ printf("Queue is Full!"); return -1; } rear++; (*Q)[rear] = item; return rear; } int main(void){ Stack_t s = {.rear = -1}; Stack_t q = {.Q = {0, 1, 2, 3, 4, 5}}; int arr[10] = {0, 1, 2, 3, 4, 5}; int item = 2; int result; int size = sizeof(q.Q)/sizeof(q.Q[0]); result = enqueue(&q.Q, item, size); printf("\nResult: {%i}", q.Q[result]); return 0; }
刚接触结构体索引,怀疑是q.Q写法问题或大小未正确获取,请求排查错误原因。
错误原因分析
- 函数参数类型非法:
int(*Q)[]是指向未知大小数组的指针,C语言无法通过这种指针计算数组元素的内存偏移量,直接用(*Q)[rear]访问会导致内存地址计算错误,触发段错误。应改为int *Q(直接传递数组首地址)或指定大小的数组指针int(*Q)[MAXSIZE]。 rear变量未初始化:两个实现的enqueue函数中,局部变量int rear;未初始化,其值为随机垃圾值。这会导致溢出判断完全失效,甚至可能直接访问超出数组范围的内存,是段错误的核心诱因之一。- 队列状态未绑定结构体:原算法中的
Rear是队列的核心状态变量,应该和数组Q一起保存在Stack_t(建议改名为Queue_t更合理)结构体中,但两个实现都未使用结构体自带的rear字段,而是定义了局部rear,完全偏离了队列的状态管理逻辑。 - “可运行”代码的隐性问题:
int(*Q)[item]的写法不符合C语法规则,item作为函数参数不能用来定义数组指针的大小;输出的“Queue is Full!”是随机命中的结果,逻辑完全不可靠。
修正后的示例代码
#define MAXSIZE 255 typedef struct Queue { int Q[MAXSIZE]; int rear; } Queue_t; // 正确的入队函数:绑定结构体管理队列状态 int enqueue(Queue_t *queue, int item) { // 检查队列溢出 if (queue->rear == MAXSIZE - 1) { printf("Queue is Full!"); return -1; } queue->rear++; queue->Q[queue->rear] = item; return queue->rear; } int main(void){ // 初始化队列:rear从-1开始表示空队列 Queue_t q = {.rear = -1}; int item = 2; int result = enqueue(&q, item); if (result != -1) { printf("\nResult: {%i}", q.Q[result]); } return 0; }
内容的提问来源于stack exchange,提问作者Emil11
相关产品推荐
相关产品推荐

