【问题标题】:C Queue cleanup pointersC 队列清理指针
【发布时间】:2014-09-23 07:51:38
【问题描述】:

您好,我在 C 中基于 LinkedList 队列编写简单的代码,但在释放指针时遇到了问题。

我在删除队列时遇到问题。函数 QueueDestroy 应该迭代整个队列并按顺序删除第一个元素,然后是下一个和下一个直到结束。

删除第一个元素是通过 QueueDeleteFirst(struct * Queue) 函数检查第一个元素是否与后元素相同

void QueueDeleteFirst(struct Queue * queue){ 
    if(queue->front == queue->rear){
        free(queue->front);
        // free(queue->rear); //This Give me "double free or corruption (fasttop)"
        //So I only set rear to null
        queue->rear = NULL;
     } else {
         queueNodeT * tmp = queue->front->next;
         free(queue->front);
         queue->front = tmp;
     }
}

我的问题是关于这个 (QueueDeleteFirst) 函数的正确性,因为我正在学习 C 并且需要一些指导。

我知道在 C 中将指针传递给函数是按值传递的,所以我有本地副本,但在我的情况下我不需要传递

struct Queue ** queue

因为我只需要释放第一个元素而不是整个结构队列。那么删除第一个元素是正确的方法吗?

接下来是 QueueDestroy(struct Queue ** queue) 这里我需要使用双指针,因为我需要 free(queue) 指针,而 QueueDestroy(struct Queue * queue) 只会释放本地指针副本?

下面是我的全部代码:

队列.h

typedef char queueElementT;

typedef struct queueNodeTag {
              queueElementT element;
              struct queueNodeTag *next;
            } queueNodeT;

struct Queue {
    queueNodeT *front, *rear;
                } ;

void QueueDestroy(struct Queue * queue);
void QueueEnter(struct Queue * queue, queueElementT element);
void QueueDeleteFirst(struct Queue ** queue);
int QueueIsEmpty(struct Queue * queue);
struct Queue * QueueCreate(void);

queue.c

#include "queue.h"

static queueNodeT *NewNode(queueElementT element);

struct Queue * QueueCreate(void){
  struct Queue * queue;
  queue = (struct Queue *)malloc(sizeof(struct Queue));
  if (queue == NULL) {
    fprintf(stderr, "Insufficient memory for new queue.\n");
    exit(1);  
  }
  queue->front = queue->rear = NULL;
  return queue;
}

void QueueDestroy(struct Queue ** queue){
  while (!QueueIsEmpty(*queue))
      QueueDeleteFirst(*queue);
  (*queue)->front = (*queue)->rear = NULL;
  free(*queue);
  *queue = NULL;
}

void QueueEnter(struct Queue * queue, queueElementT element) {
  queueNodeT *newNodeP;
  newNodeP = NewNode(element);

  if (queue->front == NULL) {  /* Queue is empty */
    queue->front = queue->rear = newNodeP;
  } else {
    queue->rear->next = newNodeP;
    queue->rear = newNodeP;
  }
}

static queueNodeT *NewNode(queueElementT element){
  queueNodeT *newNodeP;
  newNodeP = (queueNodeT *)malloc(sizeof(queueNodeT));
  if (newNodeP == NULL) {
    fprintf(stderr, "Insufficient memory for new node.\n");
    exit(1); 
  }

  newNodeP->element = element;
  newNodeP->next = NULL;

  return newNodeP;
}

int QueueIsEmpty(struct Queue * queue){
    return queue->front == NULL || queue->rear == NULL;
}

void QueueDeleteFirst(struct Queue * queue){
    if(queue->front == queue->rear){
        free(queue->front);
        queue->rear = NULL;
     } else {
         queueNodeT * tmp = queue->front->next;
         free(queue->front);
         queue->front = tmp;
     }
}

【问题讨论】:

    标签: c pointers queue


    【解决方案1】:

    您对参数传递的理解非常正确,但是您的QueueDeleteFirst 中有逻辑错误。释放前端时,您还隐含地 free rear 元素,并且两个指针都应设置为 NULL (queue->front = queue->rear = NULL)。这将解决您的清理问题。

    我看不到QueueDestroy 将如何编译,因为queue->front 不存在?

    【讨论】:

    • Sorry this is error in QueueDestroy 应该写成 (*queue)->front = (*queue)->rear = NULL;
    • 现在可以了吗? (编辑后 (*queue)->front = (*queue)->rear = NULL )
    • 对我来说似乎可以编译:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-23
    • 1970-01-01
    • 1970-01-01
    • 2018-04-30
    • 1970-01-01
    相关资源
    最近更新 更多