我正在尝试编写代码来学习队列。 该代码工作了一段时间,然后突然出现一个错误,遗憾的是我在运行代码时无法解决该错误,构建解决方案没有带来任何错误。
它似乎是在函数“dequeueLast”中触发的,并释放“dequeue”中的内存分配。
任何帮助将不胜感激!
我发布了整个代码,以防有人想自己运行它。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node
{
int data;
struct node *next;
}NODE;
typedef struct Queue
{
NODE *head;
NODE *tail;
} QUEUE;
void FREE(QUEUE *q);
void enqueue(QUEUE *q, int data);
int dequeue(QUEUE *q);
int empty(QUEUE q);
void PrintQueue(QUEUE q);
void initQueue(QUEUE *q);
void enqueue(QUEUE *q, int data)
{
NODE *newnode = (NODE*)malloc(sizeof(NODE));
if (newnode == NULL)
{
printf("overflow\n");
exit(1);
}
newnode->next = NULL;
newnode->data = data;
if (empty(*q))
{
q->head = newnode;
q->tail = q->head;
}
else
{
q->tail->next = newnode;
q->tail = newnode;
}
}
int dequeue(QUEUE *q)
{
int data;
NODE *tmp;
if (empty(*q))
return 0;
else {
tmp = q->head;
q->head = tmp->next;
if (q->head == NULL)
q->tail = NULL;
data = tmp->data;
free(tmp);
}
return data;
}
int empty(QUEUE q)
{
if ((q.head == NULL) && (q.tail == NULL))
return 1;
return 0;
}
void PrintQueue(QUEUE q)
{
int data;
QUEUE tmp;
initQueue(&tmp);
while (!empty(q))
{
data = dequeue(&q);
printf(" %d ", data);
enqueue(&tmp, data);
}
while (!empty(tmp))
enqueue(&q, dequeue(&tmp));
}
void FREE(QUEUE *q)
{
while (!empty(*q))
dequeue(q);
}
void initQueue(QUEUE *q)
{
q->head = q->tail = NULL;
}
int dequeueLast(QUEUE *q)
{
int data;
int savedData;
QUEUE *tmpQ = (QUEUE*)calloc(1, sizeof(QUEUE));
initQueue(tmpQ);
while ((q->head) != (q->tail))
{
data = dequeue(q);
enqueue(tmpQ, data);
}
savedData = q->tail->data;
FREE(q);
while (!empty(*tmpQ))
enqueue(q, dequeue(tmpQ));
FREE(tmpQ);
free(tmpQ);
return savedData;
}
int queueLength(QUEUE *q)
{
int data;
int counter = 0;
QUEUE *tmpQ1 = (QUEUE*)calloc(1, sizeof(QUEUE));
initQueue(tmpQ1);
while (!empty(*q))
{
data = dequeue(q);
enqueue(tmpQ1, data);
counter++;
}
FREE(q);
while (!empty(*tmpQ1))
enqueue(q, dequeue(tmpQ1));
FREE(tmpQ1);
free(tmpQ1);
return counter;
}
void main()
{
int num, data, lengthQ;
QUEUE *queue = (QUEUE*)calloc(1, sizeof(QUEUE));
initQueue(queue);
for (int i = 0; i < 5; i++)
{
printf("please enter a number: ");
scanf_s("%d", &num);
enqueue(queue, num);
}
printf("Original queue:");
PrintQueue(*queue);
printf("\n");
data = dequeueLast(queue);
printf("Queue after removal of last piece:");
PrintQueue(*queue);
printf("\n");
lengthQ = queueLength(queue);
printf("Queue length after removal is: %d\n", lengthQ);
system("pause");
}
最佳答案
关于:
int dequeueLast(QUEUE *q)
{
int data;
int savedData;
QUEUE *tmpQ = (QUEUE*)calloc(1, sizeof(QUEUE));
initQueue(tmpQ);
while ((q->head) != (q->tail))
{
data = dequeue(q);
enqueue(tmpQ, data);
}
savedData = q->tail->data;
FREE(q);
while (!empty(*tmpQ))
enqueue(q, dequeue(tmpQ));
FREE(tmpQ);
free(tmpQ);
return savedData;
}
此函数的大部分内容都无法实现您想要的功能。
并且返回值被分配给main()
中的局部变量,但没有使用。
建议:
void dequeueLast(QUEUE *q)
{
NODE *current == q->head;
NODE *previous = q->tail;
while( current->next )
{
previous = current;
current = current->next;
}
if( previous )
{
previous->next = NULL;
free( current );
q->tail = previous;
}
}
建议的更改有几个原因,包括删除队列中每个现有节点的所有不需要的排队和出队,以及队列中最后一个节点中的数据值实际上并未使用。
此外,通过稍微重新安排函数的顺序,可以删除所有原型(prototype)
另外,在函数中:PrintfQueue()
不要创建一个完整的新队列,而只是遍历队列,类似于:
void PrintQueue(QUEUE *q)
{
NODE *current = q->head;
while ( current->next )
{
printf(" %d ", current->data);
current = current->next;
}
}
所有对 PrintQueue()
的调用应该是:
PrintQueue( queue );
因为 queue
已经是一个指针,并且将指针传递给结构而不是完整的结构要好得多
OT:关于:
scanf_s("%d", &num);
当调用任何 scanf()
系列函数时,请始终检查返回值(而不是参数值)以确保操作成功,即
if( scanf_s("%d", &num) != 1 )
{
fprintf( stderr, "scanf_s to input a number failed" );
}
发布的代码中还有很多问题,但上面的内容应该可以让您瞄准正确的方向
关于无法解决调试错误 "ValidHeapPointer(Block)",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55984291/