Программа с несколькими стеками на языке C показывает некорректный элемент после определенного количества преднамеренных переполнений и крайних случаев автоматического удаления - PullRequest
0 голосов
/ 09 февраля 2019

Вот программа на C, над которой я сейчас работаю, которая должна позволить пользователям обрабатывать до 5 стеков за раз, и она автоматически удалит самый верхний элемент перед добавлением указанного пользователем числа, если рассматриваемый стек заполнен.Однако он страдает от кракена, в котором после преднамеренного переполнения трех или более различных стеков и, соответственно, запуска функции автоотключения, функция «показывать все элементы во всех стеках» вместо этого начнет отображать неверные результаты.

ЛибоЯ пропустил что-то или Кракена Полтергейста в игре.

Исходный код:

#include <stdio.h>
#include <malloc.h>
#define MAX 4
int stack[MAX], topA = -1;
int stackb[MAX], topB = -1;
int stackc[MAX], topC = -1;
int stackd[MAX], topD = -1;
int stacke[MAX], topE = -1;

void pushA(int val)
{
    if (topA == MAX)
    {
        int vala = val;
        printf("\n Bin 0 full! Removing the toppest one and proceeds to add the specified item");
        val = 0;
        val = stack[topA];
        topA--;
        stack[topA + 1] = vala;
        topA++;
        vala = 0;
    }
    else
    {
        stack[topA + 1] = val;
        topA++;
    }
}

int popA()
{
    int val;
    if (topA == -1)
    {
        printf("\n Underflow");
    }
    else
    {
        val = stack[topA];
        topA--;
    }
    return val;
}

void display_stackA()
{
    int i;
    if (topA == -1)
        printf("\n Stack A is empty");
    else
    {
        for (i = topA; i >= 0; i--)
            printf("\t %d", stack[i]);
    }
}

void pushB(int val)
{
    if (topB == MAX)
    {
        int valb = val;
        printf("\n Bin 1 full! Removing the toppest one and proceeds to add the specified item");
        val = 0;
        val = stackb[topB];
        topB--;
        stackb[topB + 1] = valb;
        topB++;
        valb = 0;
    }
    else
    {
        stackb[topB + 1] = val;
        topB++;
    }
}

int popB()
{
    int val;
    if (topB == -1)
    {
        printf("\n Underflow");
    }
    else
    {
        val = stackb[topB];
        topB--;
    }
}

void display_stackB()
{
    int i;
    if (topB == -1)
        printf("\n Stack B is Empty");
    else
    {
        for (i = topB; i >= 0; i--)
            printf("\t %d", stackb[i]);
    }
}

void pushC(int val)
{
    if (topC == MAX)
    {
        int valc = val;
        printf("\n Bin 2 full! Removing the toppest one and proceeds to add the specified item");
        val = 0;
        val = stackc[topC];
        topC--;
        stackc[topC + 1] = valc;
        topC++;
        valc = 0;
    }
    else
    {
        stackc[topC + 1] = val;
        topC++;
    }
}

int popC()
{
    int val;
    if (topC == -1)
    {
        printf("\n Underflow");
    }
    else
    {
        val = stackc[topC];
        topC--;
    }
}

void display_stackC()
{
    int i;
    if (topC == -1)
        printf("\n Stack C is Empty");
    else
    {
        for (i = topC; i >= 0; i--)
            printf("\t %d", stackc[i]);
    }
}

void pushD(int val)
{
    if (topD == MAX)
    {
        int vald = val;
        printf("\n Bin 3 full! Removing the toppest one and proceeds to add the specified item");
        val = 0;
        val = stackd[topD];
        topD--;
        stackd[topD + 1] = vald;
        topD++;
        vald = 0;
    }
    else
    {
        stackd[topD + 1] = val;
        topD++;
    }
}

int popD()
{
    int val;
    if (topD == -1)
    {
        printf("\n Underflow");
    }
    else
    {
        val = stackd[topD];
        topD--;
    }
}

void display_stackD()
{
    int i;
    if (topD == -1)
        printf("\n Stack D is Empty");
    else
    {
        for (i = topD; i >= 0; i--)
            printf("\t %d", stackd[i]);
    }
}

void pushE(int val)
{
    if (topE == MAX)
    {
        int vale = val;
        printf("\n Bin 4 full! Removing the toppest one and proceeds to add the specified item");
        val = 0;
        val = stacke[topE];
        topE--;
        stacke[topE + 1] = vale;
        topE++;
        vale = 0;
    }
    else
    {
        stacke[topE + 1] = val;
        topE++;
    }
}

int popE()
{
    int val;
    if (topE == -1)
    {
        printf("\n Underflow");
    }
    else
    {
        val = stacke[topE];
        topE--;
    }
}

void display_stackE()
{
    int i;
    if (topE == -1)
        printf("\n Stack E is Empty");
    else
    {
        for (i = topE; i >= 0; i--)
            printf("\t %d", stacke[i]);
    }
}

int main()
{
    int option, options, val;
    val = 0;
    do
    {
        printf("\n -----Menu----- ");
        printf("\n 1. PUSH a element");
        printf("\n 2. POP a element");
        printf("\n 3. Display all items");
        printf("\n 4. Exit");
        printf("\n Enter your choice");
        scanf("%d", &option);
        if (option == 1)
        {
            printf("\n Select ID no (0-4)");
            scanf("%d", &options);
            printf("\n Enter the value to push on your selected id:");
            scanf("%d", &val);
            if (options == 0)
            {
                pushA(val);
            }
            if (options == 1)
            {
                pushB(val);
            }

            if (options == 2)
            {
                pushC(val);
            }

            if (options == 3)
            {
                pushD(val);
            }

            if (options == 4)
            {
                pushE(val);
            }
        }

        if (option == 2)
        {
            printf("\n Select ID no (0-4) to pop");
            scanf("%d", &options);
            if (options == 0)
            {
                printf("\n Toppest item popped from ID 0");
                popA();
            }

            if (options == 1)
            {
                printf("\n Toppest item popped from ID 1");
                popB();
            }

            if (options == 2)
            {
                printf("\n Toppest item popped from ID 2");
                popC();
            }

            if (options == 3)
            {
                printf("\n Toppest item popped from ID 3");
                popD();
            }

            if (options == 4)
            {
                printf("\n Toppest item popped from ID 4");
                popE();
            }
        }

        if (option == 3)
        {
            printf("\n The contents of ID 0 are :\n");
            display_stackA();
            printf("\n The contents of ID 1 are :\n");
            display_stackB();
            printf("\n The contents of ID 2 are :\n");
            display_stackC();
            printf("\n The contents of ID 3 are :\n");
            display_stackD();
            printf("\n The contents of ID 4 are :\n");
            display_stackE();
        }
    } while (option != 4);
    return 0;
}

Вывод:

 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)0

 Enter the value to push on your selected id:1

 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)0

 Enter the value to push on your selected id:2

 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)0

 Enter the value to push on your selected id:3

 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)0

 Enter the value to push on your selected id:4

 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)0

 Enter the value to push on your selected id:5

 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice3

 The contents of ID 0 are :
         5       4       3       2       1
 The contents of ID 1 are :

 Stack B is Empty
 The contents of ID 2 are :

 Stack C is Empty
 The contents of ID 3 are :

 Stack D is Empty
 The contents of ID 4 are :

 Stack E is Empty
 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)0

 Enter the value to push on your selected id:6

 Bin 0 full! Removing the toppest one and proceeds to add the specified item
 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice3

 The contents of ID 0 are :
         6       4       3       2       1
 The contents of ID 1 are :

 Stack B is Empty
 The contents of ID 2 are :

 Stack C is Empty
 The contents of ID 3 are :

 Stack D is Empty
 The contents of ID 4 are :

 Stack E is Empty
 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)1

 Enter the value to push on your selected id:1

 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)1

 Enter the value to push on your selected id:2

 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)1

 Enter the value to push on your selected id:3

 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)1

 Enter the value to push on your selected id:4

 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)1

 Enter the value to push on your selected id:5

 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)1

 Enter the value to push on your selected id:6

 Bin 1 full! Removing the toppest one and proceeds to add the specified item
 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice3

 The contents of ID 0 are :
         6       4       3       2       1
 The contents of ID 1 are :
         6       4       3       2       1
 The contents of ID 2 are :

 Stack C is Empty
 The contents of ID 3 are :

 Stack D is Empty
 The contents of ID 4 are :

 Stack E is Empty
 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)2

 Enter the value to push on your selected id:1

 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice3

 The contents of ID 0 are :
         6       4       3       2       1
 The contents of ID 1 are :
         6       4       3       2       1
 The contents of ID 2 are :
         1
 The contents of ID 3 are :

 Stack D is Empty
 The contents of ID 4 are :

 Stack E is Empty
 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)2

 Enter the value to push on your selected id:2

 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)2

 Enter the value to push on your selected id:3

 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice3

 The contents of ID 0 are :
         6       4       3       2       1
 The contents of ID 1 are :
         6       4       3       2       1
 The contents of ID 2 are :
         3       2       1
 The contents of ID 3 are :

 Stack D is Empty
 The contents of ID 4 are :

 Stack E is Empty
 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)2

 Enter the value to push on your selected id:4

 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)2

 Enter the value to push on your selected id:5

 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)2

 Enter the value to push on your selected id:6

 Bin 2 full! Removing the toppest one and proceeds to add the specified item
 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice3

 The contents of ID 0 are :
         6       4       3       2       1
 The contents of ID 1 are :
         6       4       3       2       6
 The contents of ID 2 are :
         6       4       3       2       1
 The contents of ID 3 are :

 Stack D is Empty
 The contents of ID 4 are :

 Stack E is Empty
 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)3

 Enter the value to push on your selected id:1

 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)3

 Enter the value to push on your selected id:2

 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)3

 Enter the value to push on your selected id:3

 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)3

 Enter the value to push on your selected id:4

 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)3

 Enter the value to push on your selected id:5

 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)3

 Enter the value to push on your selected id:6

 Bin 3 full! Removing the toppest one and proceeds to add the specified item
 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice3

 The contents of ID 0 are :
         6       4       3       2       6
 The contents of ID 1 are :
         1       4       3       2       6
 The contents of ID 2 are :
         6       4       3       2       1
 The contents of ID 3 are :
         6       4       3       2       1
 The contents of ID 4 are :

 Stack E is Empty
 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)4

 Enter the value to push on your selected id:1

 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)4

 Enter the value to push on your selected id:2

 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)4

 Enter the value to push on your selected id:3

 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)4

 Enter the value to push on your selected id:4

 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)4

 Enter the value to push on your selected id:5

 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice1

 Select ID no (0-4)4

 Enter the value to push on your selected id:6

 Bin 4 full! Removing the toppest one and proceeds to add the specified item
 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice3

 The contents of ID 0 are :
         6       4       3       2       6
 The contents of ID 1 are :
         1       4       3       2       6
 The contents of ID 2 are :
         6       4       3       2       6
 The contents of ID 3 are :
         6       4       3       2       1
 The contents of ID 4 are :
         6       4       3       2       1
 -----Menu-----
 1. PUSH a element
 2. POP a element
 3. Display all items
 4. Exit
 Enter your choice

Ответы [ 2 ]

0 голосов
/ 10 февраля 2019

Как говорит Джонатан, таблица, объявленная с размером 4 элемента, может использовать только индексы от 0 до 3. Это мой день добра, я даю вам сокращенную версию с функциями, общими для 5 стеков.Я не проверил полностью, но это поможет вам понять это и исправить с рекомендациями Джонатана.Этот код еще можно улучшить.Ваша очередь!

#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <assert.h>
#define STACK_QTY   5
#define MAX         4

int stack[STACK_QTY][MAX];
int top[STACK_QTY];

void push(int index, int val)
{
    assert(index < STACK_QTY);

    if(top[index] == (MAX - 1)) {
        printf("\n Bin %d full! Removing the toppest one and proceeds to add "
               "the specified item", index);
        stack[index][top[index]] = val;
    }
    else {
        stack[index][++top[index]] = val;
    }
}

int pop(int index)
{
    assert(index < STACK_QTY);

    int val = -1;

    if(top[index] == -1) {
        printf("\n Underflow");
    }
    else {
        val = stack[index][top[index]--];
    }

    return val;
}

void display_stack(int index)
{
    assert(index < STACK_QTY);

    int i;
    if(top[index] == -1) {
        printf("\n Stack %c is empty", index + 'A');
    }
    else {
        for(i = top[index]; i >= 0; i--) {
            printf("\t %d",stack[index][i]);
        }
    }
}

void option1(void)
{
    unsigned int index = -1;
    int value;

    printf("\n Select ID no (0-%d)", STACK_QTY - 1);
    scanf("%u",&index);
    if (index < STACK_QTY){
        printf("\n Enter the value to push on your selected id:");
        scanf("%u",&value);

        push(index, value);
    }
    else {
        printf("error");
    }
}

void option2(void)
{
    unsigned int index;

    printf("\n Select ID no (0-%d) to pop", STACK_QTY - 1);
    scanf("%u",&index);
    if (index < STACK_QTY){
        printf("\n Toppest item popped from ID %d", index);

        printf("\nvalue = %d\n", pop(index));
    }
    else {
        printf("error");
    }
}

void option3(void)
{
    int i;

    for (i = 0; i < STACK_QTY; ++i) {
        printf("\n The contents of ID %d are :\n", i);
        display_stack(i);
    }
}

int main()
{
    int option;

    for (int i = 0; i < STACK_QTY; ++i) {
        top[i] = -1;
    }

    do {
        printf("\n -----Menu----- ");
        printf("\n 1. PUSH a element");
        printf("\n 2. POP a element");
        printf("\n 3. Display all items");
        printf("\n 4. Exit");
        printf("\n Enter your choice");
        scanf("%d", &option);
        switch(option)  {
            case 1: option1(); break;
            case 2: option2(); break;
            case 3: option3(); break;
        }
    }
    while(option != 4);

    return 0;
}
0 голосов
/ 10 февраля 2019

Ваши стопки могут содержать только 4 предмета (из-за #define MAX 4 и int stackN[MAX];), но вы не защищаете должным образом от переполнения.Например, если вы манипулируете стеком A и нажимаете 37, topA равно 0;нажмите 41 и topA равно 1;нажмите 43 и topA равно 2;push 47 и topA равно 3 (и стек заполнен), но когда вы нажимаете 51, вы не достигнете условия topA == MAX, поэтому переполняете свой стек - перезаписывая, кто что знает!(Это может быть одно из значений topN; оно может быть частью другого стека; ни то, ни другое не подходит, и то, что вы не хотели).

У меня есть веб-сайт для вас - Переполнение стека !

Самое простое исправление, вероятно, заключается в изменении семантики topN, чтобы она инициализировалась в 0 вместо -1.Затем вам необходимо отрегулировать граничные условия во всех функциях.

Вы действительно должны избегать использования такого количества функций (5 копий каждой из 3 функций).Это более важный переписать.Вы также должны использовать структуру для описания каждого стека.Вы извинитесь, если вы еще не изучили структуры (но тогда вам следует использовать массив top значений 2D-массива для данных стека. Это сделало бы необходимые исправления намного проще; у вас была бы 1/5 какмного мест для систематического редактирования.

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