我已经开始在C中实现循环队列,并且我有以下几行代码:
#include <stdio.h>
#include <stdlib.h>
#include "cirq.h"
//allocate a circular queue
cirq cq_alloc(void){
cirq cq = NULL;
element *head;
element *tail;
if((head = malloc(sizeof(struct element*))) &&
(tail = malloc(sizeof(struct element *)))){
head->content = 0; // head node keeps track of size.
tail->content = NULL;
head->next = tail;
tail->next = head;
cq = &head;
} else {
printf("ERROR: No space for more cqueues.\n");
}
return cq;
}
int cq_size(cirq q){
return (int)(*q)->content;
}
int main(){
cirq q = cq_alloc();
printf("Size of element ptr %lu\n", sizeof(struct element *));
printf("%d\n", cq_size(q));
return 0;
}
现在当我编译并运行这个程序时,注释掉main
中打印出sizeof(struct element *))
的行,程序运行正常,我得到了正确的队列大小,0。当我离开该行,打印出struct
的大小,但之后我得到segmentation fault: 11
。另外,为了清楚起见,struct element
有void *data
和struct element *next
个字段。如何在一行中添加打印内容会改变程序的行为?
编辑:cirq.h
#ifndef CIRQ_H
#define CIRQ_H
typedef struct element **cirq; // cirq handle
typedef struct element {
void *content;
struct element *next;
} element;
extern cirq cq_alloc(void);// allocate a queue
extern int cq_size(cirq q);// return the size of a queue
extern void cq_enq(cirq q, void *value);// add a value to the queue
extern void *cq_deq(cirq q);// dequeue and return a queue value
extern void *cq_peek(cirq q);// return the value at the queue head
extern void cq_rot(cirq q);// requeue the head element at the tail
extern void cq_free(cirq q);// return all space allocated to queue
#endif
答案 0 :(得分:4)
这是一种难闻的气味:
if((head = malloc(sizeof(struct element*))) &&
你正在考虑指针的大小。我认为你的意思是malloc结构本身......?
答案 1 :(得分:2)
cirq
是什么并不重要,你返回本地对象的地址是一个问题。
这里
cq = &head;
导致未定义的行为,因为它是指针head
的地址,仅当函数返回它时,它只存储在函数的本地。解除分配,因此无效。在别处使用它(在函数之外)是未定义的行为。
另外,不要typedef
指针。永远不要这样做,让代码阅读器知道它是一个指针。