Не удается решить ошибку отладки "ValidHeapPointer (Block)" - PullRequest
0 голосов
/ 04 мая 2019

Я пытаюсь написать код, чтобы узнать очередь.Код работал некоторое время, а затем внезапно у меня возникает ошибка, которую, к сожалению, я не могу решить во время выполнения кода, решение для сборки не приводит к ошибкам.

Кажется, что он запускается в функции "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 голосов
/ 04 мая 2019

относительно:

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(),всегда проверяйте возвращаемое значение (а не значения параметров), чтобы убедиться, что операция прошла успешно, IE

if( scanf_s("%d", &num) != 1 )
{
    fprintf( stderr, "scanf_s to input a number failed" );
}

В опубликованном коде есть еще много проблем, но вышеприведенное должно направить вас в правильном направлении

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...