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

时间:2019-05-04 15:56:53

标签: 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");
}

1 个答案:

答案 0 :(得分:0)

关于:

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;
    }
}

建议进行更改的原因有很多,其中包括删除队列中每个现有节点的所有不必要的排队和出队,以及实际上未使用队列中最后一个节点中的数据值。

此外,通过对功能顺序进行一些重新排列,可以删除所有原型

此外,在函数中: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" );
}

发布的代码中还有很多其他问题,但是以上内容可以使您正确地瞄准目标