无法解决调试错误 "ValidHeapPointer(Block)"

标签 c queue

我正在尝试编写代码来学习队列。 该代码工作了一段时间,然后突然出现一个错误,遗憾的是我在运行代码时无法解决该错误,构建解决方案没有带来任何错误。

它似乎是在函数“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/

相关文章:

java - 我的 peek() 方法不会返回队列的头部

grails - Grails非基于时间的排队

database - 向空表 oracle 注册更改通知

c - 为什么c中需要头文件

swift - 按顺序 Swift 执行任务

c# - 在 C# 中克隆队列

c - 在 C 中的多个函数之间传递不同的值?

c - 如何在 C 中打印项目符号点?

c - 如何在 C 代码中使用 UTF-8?

c - 如何使变量返回 N/A? (c语言)