C程序表现得很奇怪

时间:2016-01-16 21:48:37

标签: c gcc

我已经开始在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 elementvoid *datastruct 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

2 个答案:

答案 0 :(得分:4)

这是一种难闻的气味:

if((head = malloc(sizeof(struct element*))) &&

你正在考虑指针的大小。我认为你的意思是malloc结构本身......?

答案 1 :(得分:2)

cirq是什么并不重要,你返回本地对象的地址是一个问题。

这里

cq = &head;

导致未定义的行为,因为它是指针head的地址,仅当函数返回它时,它只存储在函数的本地。解除分配,因此无效。在别处使用它(在函数之外)是未定义的行为

另外,不要typedef指针。永远不要这样做,让代码阅读器知道它是一个指针