[英]Multiple stack program in C Language shows incorrect element after a certain amount of intentional overflows and toppermost autoremovals
Here's the C program I'm working on right now, which should let users to handle up to 5 stacks at a go and it will autoremove the toppermost item before adding the user-specified number if the stack in question is full. 这是我现在正在使用的C程序,该程序应允许用户一次最多处理5个堆栈,并且如果有问题的堆栈已满,它将在添加用户指定的编号之前自动删除最上面的项目。 However it's been plagued by a kraken in which after 3 or more distinct stacks are intentionally overflowed and thus triggering the autoremoval function, the "show all elements at all stacks" function would begin to display incorrect results instead.
但是,它一直受到海妖的困扰,其中有意溢出3个或更多不同的堆栈并触发自动删除功能后,“显示所有堆栈中的所有元素”功能将开始显示错误的结果。
Either I've missed something or a poltergeist kraken at play. 我要么错过了什么,要么在玩耍时狂妄自大。
Source code: 源代码:
#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;
}
Output: 输出:
-----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
As Jonathan says, a table declared with a size of 4 elements can only use the indices of 0 to 3. It's my day of goodness, I give you a condensed version with functions common to 5 stacks. 正如Jonathan所说,声明为4个元素的表只能使用0到3的索引。这是我的天,我为您提供了5个堆栈具有通用功能的精简版本。 I have not tested completely, but it will do you a good exercise to understand it and correct it with the recommendations of Jonathan.
我还没有完全测试过,但是通过Jonathan的建议,它可以帮助您理解和更正它。 This code can still be improved.
此代码仍可以改进。 Your turn !
轮到你了 !
#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;
}
Your stacks can only hold 4 items (because of #define MAX 4
and int stackN[MAX];
) but you don't protect properly against overflow. 您的堆栈只能容纳4个项目(由于
#define MAX 4
和int stackN[MAX];
),但是您不能适当地防止溢出。 For example, if you manipulate stack A and push 37, topA
is 0; 例如,如果您操纵堆栈A并推入37,则
topA
为0; topA
, topA
为0。 push 41 and topA
is 1; 推41,
topA
为1; push 43 and topA
is 2; 推43,
topA
为2; push 47 and topA
is 3 (and the stack is full), but when you push 51, you don't hit the topA == MAX
condition, so you overflow your stack — overwriting who knows what! 推动47,
topA
为3(堆栈已满),但是当您推动51时,您没有达到topA == MAX
条件,因此您的堆栈溢出了—覆盖谁知道! (It might be one of the topN
values; it might be part of another stack; neither is good, and neither is what you intended.) (它可能是
topN
值之一;它可能是另一个堆栈的一部分;都不是好事,也不是您想要的。)
I've got a web site for you — Stack Overflow ! 我为您提供了一个网站-Stack Overflow !
The simplest fix is probably to change the semantics of topN
so that it is initialized to 0 instead of -1
. 最简单的解决方法可能是更改
topN
的语义,以便将其初始化为0而不是-1
。 You then have to adjust the edge conditions in all the functions. 然后,您必须在所有功能中调整边缘条件。
You really need to avoid having so many functions (5 copies of each of 3 functions). 您确实需要避免拥有太多功能(3个功能中的每个功能有5个副本)。 That's a more major rewrite.
这是一个更主要的重写。 You should also use a structure to describe each stack.
您还应该使用一种结构来描述每个堆栈。 You're excused if you've not learned structures yet (but then you should use an array of
top
values a 2D array for the stack data. That would make the fixes needed much easier; you'd have 1/5th as many places to edit systematically. 如果您还没有学习过结构,那么您会被原谅(但是您应该使用一个
top
值数组和一个用于堆栈数据的2D数组。这将使所需的修复更加容易;您所需要的位置将是原来的1/5进行系统编辑。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.