簡體   English   中英

如何調試“索引超出范圍”異常? 還是可以在引發異常時讓VS進入調試模式?

[英]How can I debug an “Index was out of range” exception? Or can I make VS enter debug mode when an exception is thrown?

我的問題是,我得到了一個Index was out of range引發異常,並且我想弄清楚到底發生了什么以及導致錯誤的特定數組和索引是什么。 我只是簡單地遍歷程序來查找它,因為它使用訪問運算符[]的次數為數百萬次。 那么,有什么方法可以讓我的程序“后退”並在引發異常時進入調試模式? 除了要花費數小時才能完成的蠻力行動外,我無法解決其他解決方案。

這是一個完整的代碼轉儲,以防萬一:

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

namespace StringSet
{


    class StringSet
    {

        private List<List<string>> _Buckets;
        public int NumStrings { get; private set; }

        public StringSet ( ) 
        {
            this._Buckets = new List<List<string>>();
            this.NumStrings = 0;
        }

        public StringSet ( string[] S )
        {
            // better way to do this?
            this._Buckets = new List<List<string>>();
            foreach ( string s in S ) this._Buckets.Add(new List<string>());
            foreach ( string s in S ) { this.Insert(s);  }
        }

        private int _GetBucketNumber ( string s, List<List<string>> Buckets )
        {
            //       s: string whose index to look up
            // Buckets: source buckets

            // disallow empty or NULL strings
            if ( String.IsNullOrEmpty(s) ) { throw new ArgumentException("Cannot add empty or NULL string to set"); }
            if ( Buckets.Count == 0 ) { throw new ArgumentException("Tried to call _GetBucketNumber on empty bucket list"); }

            // Bernstein hash
            // http://www.eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx           
            int result = (int)s[0];
            for ( int i = 1; i < s.Length; ++i ) { result = 33 * result + (int)s[i]; }
            return result % Buckets.Count;
        }

        private void _RehashIfNecessary ( )
        {
            // if the number of strings in the set exceeds the number of buckets, 
            // increase the number of buckets to either double its current size 
            // or the largest number of buckets possible, whichever is smaller
            if ( this.NumStrings > this._Buckets.Count )
            {
                List<List<string>> NewBuckets = new List<List<string>>(Math.Min(this._Buckets.Count * 2, Int32.MaxValue));
                foreach ( List<string> Bucket in this._Buckets )
                {
                    foreach ( string s in Bucket )
                    {
                        NewBuckets[this._GetBucketNumber(s, NewBuckets)].Add(s);
                    }
                }
                this._Buckets = NewBuckets;
            }
        }

        public void Insert ( string s )
        {
            // disallow empty or NULL strings
            if ( String.IsNullOrEmpty(s) ) { throw new ArgumentException("Cannot add empty or NULL string to set"); }

            // Get bucket that string belongs in
            int k = this._GetBucketNumber(s, this._Buckets);
            if (k >= this._Buckets.Count) { Console.WriteLine("Found problem! GetBucketNumber return {0}, whichs is bigger or equal to than this._Buckets.Count={1}", k, this._Buckets.Count); }
            List<string> Bucket = this._Buckets[this._GetBucketNumber(s,this._Buckets)];
            // Add if not already there
            if ( Bucket.IndexOf(s) == -1 ) { Bucket.Add(s); }
            ++NumStrings; _RehashIfNecessary();
        }

        public bool Contains ( string s )
        {
            // returns true or false depending on whether s is a 
            // string currently in the set
            return (this._Buckets[this._GetBucketNumber(s,this._Buckets)].IndexOf(s) != -1);
        }

        public void RunPerformanceTest ( )
        {
            // tests string hash set against regular List<string> 
            // in terms of lookup

            // create list of all elements in hash set
            List<string> ListVersion = new List<string>(),
                                Copy = new List<string>();
            foreach ( List<string> Bucket in this._Buckets )
            {
                foreach ( string Str in Bucket )
                {
                    ListVersion.Add(Str);
                    Copy.Add(Str);
                }                    
            }

            // calculate average time to look up all elements
            Stopwatch Watch = new Stopwatch();
            long tList = 0, tHset = 0; // ms
            foreach ( string Str in Copy )
            {
                // measure time to look up string in ordinary list
                Watch.Start();
                if ( ListVersion.Contains(Str) ) { }
                Watch.Stop();
                tList += Watch.ElapsedTicks;
                // now measure time to look up same string in my hash set
                Watch.Reset();
                Watch.Start();
                if ( this.Contains(Str) ) { }
                Watch.Stop();
                tHset += Watch.ElapsedTicks;
                Watch.Reset();
            }
            int n = Copy.Count;
            Console.WriteLine("Average ticks to look up in List: {0}", tList / n);
            Console.WriteLine("Average ticks to look up in hashset: {0}", tHset / n);
        }

        public void Print ( )
        {
            for ( int i = 0; i < this._Buckets.Count; ++i )
            {
                Console.WriteLine("Bucket {0}: {1}", i, string.Join(",",this._Buckets[i].ToArray()));
            }
        }

    }

    class Program
    {
        static void Main ( string[] args )
        {

            try
            {
                List<string> Words = new List<string>();
                Console.WriteLine("Reading dictionary words from text file into hash set ...");
                System.IO.StreamReader file = new System.IO.StreamReader(System.AppDomain.CurrentDomain.BaseDirectory + "testfiles\\dictionary.txt");
                string line; 
                while ( (line = file.ReadLine()) != null )
                {
                    Words.Add(line);
                }
                Console.WriteLine("DONE!");
                StringSet TestSet = new StringSet(Words.ToArray());
                Console.WriteLine("Running performance test ...");
                TestSet.RunPerformanceTest();
                Console.WriteLine("DONE!");
            }
            catch ( Exception E )
            {
                Console.WriteLine("Exception occured: {0}", E.Message);
            }
            Console.Read(); // just to keep console open
        }
    }
}

是的,您可以在引發錯誤時使VS停止。 不同版本之間可能略有不同,但通常在菜單上:“調試”>“異常...”。

然后展開“公共語言運行時異常-系統”,並在“拋出”列中選中您的異常框

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM