#c #data-structures #stack
#c #структуры данных #стек
Вопрос:
По сути, я создал функцию create_app() для выделения 2 узлов в стеке, каждый из которых имеет указатель на массив [max]; undo() извлекает последний элемент и, прежде чем вернуть его, добавляет его в массив узла ПОВТОРА. redo() делает обратное, извлекает последний элемент в своем массиве, помещая его в массив отмены, прежде чем возвращать его. Что я сделал не так?
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#define EMPTY_TOS (-1)
typedef struct node *node_ptr;
struct node
{
int arr_size;
int tos;
int *arr_stack;
node_ptr next;
};
typedef node_ptr STACK;
STACK
create_app(int max)
{
STACK UNDO = (STACK) malloc(sizeof(struct node));
STACK REDO = (STACK) malloc(sizeof(struct node));
{
UNDO->arr_stack == (int *) malloc(max * sizeof(int));
REDO->arr_stack == (int *) malloc(max * sizeof(int));
if(UNDO->arr_stack != NULL){printf("Out of space!");}
else
{
UNDO->tos = EMPTY_TOS;
REDO->tos = EMPTY_TOS;
UNDO->arr_size = max;
REDO->arr_size = max;
UNDO->next = REDO;
REDO->next = UNDO;
return UNDO;
}
}
}
int
isEmpty(STACK S)
{
return(S->tos==-1);
}
int
isFull(STACK S)
{
return(S->tos>=S->arr_size-1);
}
void
push(int x, STACK S)
{
if(isFull(S)){printf("Stack full!");}
else
{
S->arr_stack[ S->tos] = x;
}
}
int
undo(STACK S)
{
if(isEmpty(S)){printf("Nothing to undo!");}
else
{
S->next->arr_stack[ S->next->tos] = S->arr_stack[S->tos];
printf("%d",S->arr_stack[S->tos--]);
}
}
int
redo(STACK S)
{
if(isEmpty(S->next)){printf("Nothing to redo!");}
else
{
int temp = S->next->arr_stack[S->next->tos];
push(S->next->arr_stack[S->next->tos], S);
S->next->tos--;
printf("%d",temp);
}
}
int main()
{
STACK app = create_app(5);
push(1,app);
push(2,app);
push(3,app);
undo(app);
undo(app);
redo(app);
redo(app);
/* Expected output: 3223 */
return 0;
}
Ответ №1:
В вашем коде были некоторые небольшие ошибки, подобные этим, create_app()
которые кажутся опечатками.
UNDO->arr_stack == (int *) malloc(max * sizeof(int));
REDO->arr_stack == (int *) malloc(max * sizeof(int));
^
|
if(UNDO->arr_stack != NULL){printf("Out of space!");}
^
|
...
и некоторые int
возвращаемые функции ничего не возвращали в той else
части, которая выдавала некоторые предупреждения.
Вот измененный код, который отлично работал для меня
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#define EMPTY_TOS (-1)
typedef struct node* node_ptr;
struct node
{
int arr_size;
int tos;
int *arr_stack;
node_ptr next;
};
typedef node_ptr STACK;
STACK
create_app(int max)
{
STACK UNDO = (STACK) malloc(sizeof(struct node));
STACK REDO = (STACK) malloc(sizeof(struct node));
{
UNDO->arr_stack = (int *) malloc(max * sizeof(int));
REDO->arr_stack = (int *) malloc(max * sizeof(int));
if(UNDO->arr_stack == NULL){printf("Out of space!");
return NULL;}
else
{
UNDO->tos = EMPTY_TOS;
REDO->tos = EMPTY_TOS;
UNDO->arr_size = max;
REDO->arr_size = max;
UNDO->next = REDO;
REDO->next = UNDO;
return UNDO;
}
}
}
int
isEmpty(STACK S)
{
return (S->tos == -1);
}
int
isFull(STACK S)
{
return (S->tos >= S->arr_size-1);
}
void
push(int x, STACK S)
{
if(isFull(S)){printf("Stack full!");}
else
{
S->arr_stack[ S->tos] = x;
}
}
void
undo(STACK S)
{
if(isEmpty(S)){printf("Nothing to undo!");}
else
{
S->next->arr_stack[ S->next->tos] = S->arr_stack[S->tos];
printf("%d",S->arr_stack[S->tos--]);
}
}
void
redo(STACK S)
{
if(isEmpty(S->next)){printf("Nothing to redo!");}
else
{
int temp = S->next->arr_stack[S->next->tos];
push(S->next->arr_stack[S->next->tos], S);
S->next->tos--;
printf("%d",temp);
}
}
int main()
{
STACK app = create_app(5);
push(1,app);
push(2,app);
push(3,app);
undo(app);
undo(app);
redo(app);
redo(app);
/* Expected output: 3223 */
return 0;
}
Результат:
3223
Однако всегда принимайте меры предосторожности при освобождении malloc
используемой памяти free()
.
Комментарии:
1. Спасибо! Совершенно забыл освободить память. @swag2198 Если я освобожу (приложение), я освобожу оба узла для ОТМЕНЫ и ПОВТОРА?
2. Нет. Вы должны освободить каждый из стеков ОТМЕНЫ и повтора по отдельности. Также вам нужно освободить массивы, которые вы выделили внутри них. По сути, для каждого malloc потребуется соответствующий free.
3. хорошо, итак, free (S) free (S-> next) и установка tos для каждого arr на -1 (или free (S-> arr_stack) и free (S-> next-> arr_stack)) достаточно?
4. ДА. Сначала освободите
arr_stack
массивы, а затемS->next
иS
. Обратите внимание, что установкаtos
значения -1 не освобождает массивы.5. Понял! Большое спасибо 🙂