异常说堆栈不是空的?

Posted

技术标签:

【中文标题】异常说堆栈不是空的?【英文标题】:Exception says stack is empty when it is not? 【发布时间】:2015-04-05 22:36:18 【问题描述】:

我在我的书中学习了一些advanced collections 等,并且遇到了stacks。我明白了这个概念,但想制作一个快速程序,从defined point in the stack 然后places all the values back onto the stack 中删除一个项目。我在这里有我的代码,但我得到了 System.InvalidOperationException 类型的异常,堆栈的附加信息为空。我似乎不明白为什么;谁能帮忙?

这是我的代码:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace StackRemover

    class Program
    
        static void Main(string[] args)
        
            int index = 0; //the index they want to remove
            Stack[] array = new Stack[1]; // will hold the array returned by remove()
            Stack stack = new Stack();

            //fill the stack with values from 0 to 100
            for (int y = 0; y != 100; y++ )
            
                stack.Push(y);
            

            //print all items from stack
            foreach (var item in stack) 
            
                Console.WriteLine(item.ToString());
            

            Console.WriteLine("\n\nEnter an index to remove: ");
            index = Convert.ToInt32(Console.ReadLine());
            array = remover(stack, index);

            Console.WriteLine("\n\n" + array[1].Pop().ToString() + "\n\n"); //print the value of the removed index

            //print the rest of the values
            foreach(var item in array[0])
            
                Console.WriteLine(item.ToString());
            
        

        public static Stack[] remover(Stack stack, int index)
        
            Stack holding_stack = new Stack(); // used for holding values temporarily
            Stack value_stack = new Stack();   // will be returned with the desired index only
            int stack_length = stack.Count;
            int target = index - 1; // the index before the one we want to remove
            int current_index = 0;

            //if the index is larger than the stack size
            if(index > stack_length)
            
                throw new Exception("Index bigger than stack!");
            

            //pop items from stack and place them onto a temporary stack until we reach target
            while(current_index != target)
            
                holding_stack.Push(stack.Pop()); //ERROR OCCURS HERE, System.InvalidOperationException, says that the stack is empty?
            

            value_stack.Push(stack.Pop()); // push the index we were passed onto our third stack

            //place all the values from the holding stack back onto the passed stack
            while(holding_stack.Count != 0)
            
                stack.Push(holding_stack.Pop());
            

            return new Stack[]stack, value_stack;

        
    

【问题讨论】:

您声明 array 的大小为 1,但访问其第二个元素 array[1].Pop() 【参考方案1】:

好吧,我在本节看到一个问题:

if(index > stack_length)

    throw new Exception("Index bigger than stack!");

应该是index >= stack_length,因为如果您的堆栈中有 100 个项目并且您尝试获取 第 100 个 索引,那么您将超出范围,因为最后一项将位于索引 99

【讨论】:

好的,谢谢。这只是一个帮助我理解堆栈的快速程序,似乎我可以犯像这样的 rofl 愚蠢的错误。 @Sicarius Programming 与数学有一个有趣的共同点——魔鬼在细节中。这些错误可能很愚蠢,但您必须训练自己密切关注,否则您的手上会出现漏洞百出的程序。 是的,我知道。我想它最终会来找我;谢谢你的建议。【参考方案2】:

看看你的循环:

while(current_index != target)

    holding_stack.Push(stack.Pop());

您希望该循环如何结束?您不会在循环体中更改 targetcurrent_index ... 也许您的意思是在循环中增加 current_index?如果是这样,我是否建议for 循环比while 循环更简单?

附带说明,值得遵循 .NET 命名约定 - 其中方法是 PascalCased,变量是 camelCased,没有下划线。

所以你可能会得到:

for (int i = 0; i < target; i++)

    holdingStack.Push(stack.Pop());

【讨论】:

@Sicarius 你很幸运,圣灵亲自回答了你的问题。弓。我嫉妒了。 哈哈,可惜这是一个真正的问题,而不是一个愚蠢的错误^.^

以上是关于异常说堆栈不是空的?的主要内容,如果未能解决你的问题,请参考以下文章

如何检测 Vue $router.back() 是不是已完成,而不是历史堆栈为空的情况?

如何使用 CaptureStackBackTrace 捕获异常堆栈,而不是调用堆栈?

我究竟做错了什么?堆栈与字符图形(C ++)

Laravel:是不是可以在捕获异常时记录堆栈跟踪并继续执行?

将异常的堆栈跟踪转换为 byte[] 数组或 ByteBuffer (Java) 是不是更有效?

Javascript 异常堆栈跟踪