9 svar
305 visningar
msoffer 27
Postad: 9 aug 2021 20:14

c# stack overflow

Hej!

Jag har suttit och försökt lösa detta hela eftermiddagen, har kodat om allt 1 gång osv. Men när jag testkör programmet står det enbart "stack overflow". Kan någon försöka hjälpa mig förstå varför och hur jag ska lösa det?

Vore evigt tacksam!

using System;
using System.Collections.Generic; // katalog för att ha möjlighet att sortera vektorn 

namespace jagblirgalen
{
        namespace candycrate
        {
            public class Candy      // klass för godiset
            {
                private string namn; // objekt som håller namn, sort och pris på godiset 
                private string sort;
                private string kostnad;

                public string Namn { get { return namn; } set { namn = value; } }
                public string Sort { get { return sort; } set { sort = value; } }
            public  double Kostnad { get { return Kostnad; } set { Kostnad = value; } }
              

                public Candy(string _namn, string _typ, double _kostnad)     // Konstruktor för en godis
                {
                    namn = _namn;   // innehåller namn
                    sort = sort;     // innehåller typ
                    Kostnad = _kostnad;   // innehåller pris
                }
            }

            class Candycrate
            {
                private Candy[] candys = new Candy[24];     // Vektor som tar hand om Candy objekten
                private List<Candy> candy_list = new List<Candy>();     // Meny/lista över alla godissorter

                public void content_list()          // Metod som fyller produktmenyn med få alternativ av sorter
                {
                    candy_list.Add(new Candy("Dumle orginal", "Choklad", 0.50));
                    candy_list.Add(new Candy("Japp mini", "Choklad", 0.50));
                    candy_list.Add(new Candy("Marabou mini", "Choklad", 1.50));
                    candy_list.Add(new Candy("Sur patron", "Surt godis", 1.25));
                    candy_list.Add(new Candy("Sura bläckfiskar", "Surt godis", 0.75));
                    candy_list.Add(new Candy("Dödskalle Hallon", "Surt godis", 1.00));
                    candy_list.Add(new Candy("Salt fisk", "Lakrits", 1.25));
                    candy_list.Add(new Candy("Djungelvrål", "Lakrits", 0.50));
                    candy_list.Add(new Candy("Hallonsalta karameller", "Lakrits", 2.50));
                    candy_list.Add(new Candy("Gelehallon", "Sockerfritt godis", 3.75));
                    candy_list.Add(new Candy(" Hallon/lakritsskalle", "Sockerfritt godis", 4.25));
                    candy_list.Add(new Candy(" colaflaskor", "Sockerfritt godis", 4.00));
                }
                public void stats()     // metod som visar uppdaterad info om godispåsen
                {
                    Console.Clear(); //används för att tömma menyn och göra rent.
                    Console.WriteLine("\n Godispåse-stimulatorn:");
                    Console.WriteLine(" Antal godisar i påsen [{0}/[24] total pris: {1:0.00}kronor", RecursiveBites(0), calc_total());
                    if (RecursiveBites(0) == 24)
                        Console.WriteLine("Godispåsen är nu fylld!"); // Om användaren lagt till 24 bitar i påsen
                    else
                        Console.WriteLine("");
                }
                public int RecursiveBites(int index) // Rekursiv algoritm som räknar hur många godispåsar som finns i påsen
                {
                    int antal = index < 24 && candys[index] == null ? RecursiveBites(index + 1) : index < 24 && candys[index] != null ? +1 + RecursiveBites(index + 1) : +0;
                    return antal; // kollar om ett antagande de e sant eller falskt, och sker en sak beroende på resultat.
                }
                public void Run()       // metod för huvudmenyn
                {
                    string val;
                    do                      // loopar menyn så programmet fortsätter efter menyval
                    {
                        stats();
                        Console.WriteLine("\n Meny för Godispåse-simulator"); // menyn för godis simulatorn
                        Console.WriteLine("\n Välj ditt alternativ:");
                        Console.WriteLine(" 1: Lägga till en godis");
                        Console.WriteLine(" 2: Ta bort en godis");
                        Console.WriteLine(" 3: Skriv ut godispåsen");
                        Console.WriteLine(" 4: Sök efter en godissort");
                        Console.WriteLine(" 5: Sortera godispåsen");
                        Console.WriteLine(" 0: Avsluta programmet");

                        val = Console.ReadLine();
                        switch (val)
                        {
                            case "1":                 // Val som anropar metoden add_candy
                                add_candy();
                                break;
                            case "2":                 // Val som anropar metoden remove_candy
                                tabort_candy();
                                break;
                            case "3":                 // Val som anropar metoden print_crate
                                print_crate();
                                break;
                            case "4":                 // Val som anropar metoden find_candy
                                find_candy();
                                break;
                            case "5":                 // Val som anropar metoden sort_candy
                                sort_candys();
                                break;
                            case "0":                 // Val avslutar programmet
                                break;
                        }
                    }
                    while (val != "0"); //loopets villkor
                }
                public void add_candy() // metod för att kunna lägga till godis i godispåsen
                {
                    Random slumpmässigt = new Random(); // gör så att man få en slumpmässigt utvald godisbit
                    string str;

                    do
                    {
                        stats();
                        Console.WriteLine("\n Meny: Lägg till godis"); // Skriver ut meny för add_candy 
                        Console.WriteLine("\n     {0,-17}  {1,-15} {2,6}\n", "Namn:", "Sort:", "Pris:");
                        int str_index = 1;          // heltal för att listan ska få ett synligt index
                        foreach (var candy in candy_list)
                        {
                            string formatString = String.Format(" {3,2}: {0,-18} {1,-15} {2,5:0.00}kronor", candy.Namn, candy.Sort, candy.Kostnad, str_index++);
                        }
                        Console.WriteLine("\n [S]ortera godislistan");
                        Console.WriteLine(" [L]ägg till ny godissort i påsen");
                        Console.WriteLine(" [P]acka godispåsen full");
                        Console.WriteLine(" [G]å till huvudmenyn");
                        Console.WriteLine("\n Välj godis med index att fylla påsen med");

                        str = Console.ReadLine(); // läser användarens svar
                        int val = check(str);  // Svaret kontrolleras

                        if (val != -1 && val < 25 && val > 0)     // Lägger till godis ifall svaret är korrekt 

                        {
                            for (int i = 0; i < candys.Length; i++) // vektorn loopar efter den första lediga plats 
                            {
                                if (candys[i] == null)
                                {
                                    val--;
                                    candys[i] = candy_list[val]; // vid tom plats i systemet fylls den med godis
                                    break;
                                }
                                else if (i == candys.Length - 1)         // vid ingen ledig plats är påsen full 
                                {
                                    Run();
                                }
                            }
                        }
                        else
                        {
                            if (str == "s" || str == "S")       // hoppar till sortera lista metoden
                                sort_list();
                            else if (str == "l" || str == "L")
                            {
                                stats();
                                Console.WriteLine("\n Skriv in namn, sort och pris på den nya godisen, skriv in 'Avsluta' för avbryt");
                                Console.Write(" Namn: ");
                                string namn = Console.ReadLine();
                                if (namn == "Avsluta") // vill användaren avbryta så kommer programmet gå tillbaka till metoden där man lägger till godis 
                                    break;
                                else
                                {
                                    Console.Write(" Sort: ");
                                    string sort = Console.ReadLine();
                                    Console.Write(" Pris:  ");
                                    double pris = -1;
                                    try
                                    {
                                        string temp = Console.ReadLine(); // kontrollerar så svaret är korrekt 
                                        pris = Convert.ToDouble(temp);
                                    }
                                    catch
                                    {
                                        pris = -1;
                                    }
                                    if (pris != -1)
                                    {
                                        candy_list.Add(new Candy(namn, sort, pris)); // ifall allt stämmer, så läggs den nya skapade godisen i listan
                                        Console.Clear();                // används för att hålla fönstret rent och snyggt 
                                    }
                                }
                            }
                            else if (str == "p" || str == "P")       // val som ska fylla påsen med varierade godisar
                            {
                                for (int i = 0; i < candys.Length; i++)     // vektorn loopar
                                {
                                    if (candys[i] == null)                  // fylls på enbart där de inte finns något 
                                    {
                                        int rnd = slumpmässigt.Next(1, candy_list.Count); /* Skapar en okänd siffra mellan alternativen på godislistan
                                                                   * så godisbitar man adderar i listan även dem kommer slumpas fram*/
                                        candys[i] = candy_list[rnd];
                                    }
                                }
                                break;
                            }
                            else if (str == "g" || str == "G")       // användaren kommer tillbaka till "huvud"-menyn
                                break;
                        }
                    } while (str != "g" || str != "G");
                }
                public void sort_list()       // metod för att kunna sortera listan
                {
                    stats();
                    string val;

                    Console.WriteLine(" \n Sortera menyn: ");
                    Console.WriteLine("\n Sortera enligt: ");
                    Console.WriteLine(" [N]amn");
                    Console.WriteLine(" [S]ort");
                    Console.WriteLine(" [P]ris");
                    Console.WriteLine(" [G]å till menyn");

                    val = Console.ReadLine(); // användaren väljer sitt val för sorteringen

                    if (val == "n" || val == "N")
                    {
                        candy_list.Sort((x, y) => x == null ? 1 : y == null ? -1 : x.Namn.CompareTo(y.Namn));   // väljer användaren detta så sorteras menyn enligt namn
                    }
                    else if (val == "s" || val == "S")
                    {
                        candy_list.Sort((x, y) => x == null ? 1 : y == null ? -1 : x.Sort.CompareTo(y.Sort)); // listan sorteras enligt sorter
                    }
                    else if (val == "p" || val == "P")
                    {
                        candy_list.Sort((x, y) => x == null ? 1 : y == null ? -1 : x.Kostnad.CompareTo(y.Kostnad)); // listan sorteras enligt pris 
                    }
                    else if (val == "g" || val == "G") // användaren tas tillbaka till menyn
                    {
                        Run();
                    }
                    else
                    {
                        sort_list(); // om icke korrekt inmatning
                    }
                }

                public void tabort_candy() // metod för att ta bort godis ur godissimulatorn/godispåsen
                {
                    do                      // loopar borttagningen tills användaren avbryter
                    {
                        stats();
                        Console.WriteLine("\n Ta bort godis");
                        int num = 1;
                        Console.WriteLine("\n {0,-17} {1,-13} {2,6}\n", "Namn:", "Sort:", "Pris:");

                        foreach (var candy in candys) // visar först vad som finns i påsen
                        {
                            if (candy != null)
                            {
                                string formatString = String.Format(" {3,2}: {0,-18} {1,-13} {2,5:0.00}kronor", candy.Namn, candy.Sort, candy.Kostnad, num++);
                            }
                            else // och till sist, allt utan innehåll
                            {
                                string formatString = String.Format(" {1,2}: {0}", "Ledig plats", num++);
                            }
                        }
                        Console.WriteLine("\n [R]ensa listan"); // meny där man kan välja mellan att ta bort en godis i taget eller hela godispåsen.//
                        Console.WriteLine(" [G]å till menyn");
                        Console.Write("\n Välj index att ta bort:");
                        string str = Console.ReadLine(); // användaren väljer "index att ta bort"

                        if (str == "r" || str == "R")        // val för att rensa godispåsen (vektorn)
                        {
                            for (int i = 0; i < candys.Length; i++)
                                if (candys[i] != null)
                                    candys[i] = null;
                        }
                        else if (str == "g" || str == "G")      // avbryter loopen och användaren kommer till menyn
                            break;
                        else
                        {
                            int index = check(str); // kontrollerar val 
                            if (index > 0 && index <= candys.Length)
                            {
                                index--;        // gör så man kommer rätt i vektorn då den startar vid "0"
                                candys[index] = null;

                            }
                        }
                    } while (true);
                }

                public void print_crate()
                {
                    stats();
                    Console.WriteLine("\n Innehåll i godispåsen");
                    int num = 1;
                    Console.WriteLine("\n {0,-17} {1,-15} {2,6}\n", "Namn:", "Sort:", "Pris:");

                    foreach (var candy in candys)       // loop som skriver ut påsens innehåll
                    {
                        if (candy != null)          // objekt främst
                        {
                            string formatString = string.Format("{3,2}: {0,-18} {1,-15} {2,5:0.00}kronor", candy.Namn, candy.Sort, candy.Kostnad, num++);
                        }
                        else // sist kommer lediga platser 
                        {
                            string formatString = string.Format("{1,2}: {0}", "Ledig plats", num++);
                        }
                    }
                    Console.WriteLine("\n Tryck på vilken tangent som helst för att backa till menyn....");
                    Console.ReadKey();
                }

                public double calc_total() // metod som räknar ut den totala kostnaden som finns i godispåsen
                {
                    double total_pris = 0;

                    foreach (var candy in candys)
                        if (candy != null)
                            total_pris += candy.Kostnad;
                    return total_pris;
                }

                public void find_candy() // metod för att kunna söka efter en specifik godis i påsen/vektorn
                {
                    stats();

                    int index;
                    string namn;

                    Console.WriteLine("\n Leta efter specifik godis");
                    Console.WriteLine("\n Skriv in namnet på godisen:");

                    namn = Console.ReadLine();      // användaren skriver in vad godisen heter

                    index = LinearSearch(candys, namn); // anropar metoden linjär sökning
                    if (index == -1)
                        Console.WriteLine("\n Felaktigt namn"); // meddelar om användaren skrivit fel, eller om den inte finns i simulatorn
                    else
                    {
                        Console.WriteLine("\n [0} finns, vill du:", candys[index].Namn); /* finns godisen så kan användaren välja vad 
                                                                                     * man vill göra när man hittat godisen*/
                        Console.WriteLine("\n [L]ägg till hittad godis");
                        Console.WriteLine("   [T]a bort hittad godis");
                        Console.WriteLine("   [G]å till menyn");

                        string val = Console.ReadLine(); // användaren gör sitt val

                        if (val == "l" || val == "L")       // val som fördubblar godisen
                        {
                            for (int i = 0; i < candys.Length; i++)     // Loopar vektorn efter första tomma plats
                            {
                                if (candys[i] == null)
                                {
                                    candys[i] = candys[index]; // när en ledig plats funnts läggs fylls den på med likadana godisar
                                    break;
                                }
                                else if (i == candys.Length - 1)
                                {
                                    Run();          /* Är godispåsen full är det onödigt att försöka fylla den, så 
                                                 * användaren kommer automatiskt till menyn*/
                                }
                            }
                        }
                        else if (val == "t" || val == "T")
                        {
                            candys[index] = null;
                        }
                        else if (val == "g" || val == "G")
                        {
                            Run();
                        }
                    }
                    Console.WriteLine("\n Tryck på valfri tangent för att komma till menyn");
                    Console.ReadKey();
                }

                public int LinearSearch(Candy[] candy, string key)     // metod för linjär sökning
                {
                    for (int i = 0; i < candy.Length; i++)              // Loop för att söka efter överensstämmande sträng 
                    {
                        if (candy[i] != null)
                            if (candy[i].Namn == key)
                                return i;                              // finns namnet returneras index
                    }
                    return -1;
                }

                public void sort_candys()   /* metod för att organisera i godispåsen */
                {
                    stats();

                    string val;
                    Console.WriteLine("\n Sortera meny:");
                    Console.WriteLine("\n Sortera enligt:");
                    Console.WriteLine(" [N]amn");
                    Console.WriteLine(" [S]ort");
                    Console.WriteLine(" [P]ris");
                    Console.WriteLine(" [G]å till menyn");

                    val = Console.ReadLine();       // användaren gör sitt val

                    if (val == "n" || val == "N")
                    {
                        Array.Sort(candys, (x, y) => x == null ? 1 : y == null ? -1 : x.Namn.CompareTo(y.Namn)); // Sorterar så de som finns i lager kommer först
                        print_crate();
                    }

                    else if (val == "s" || val == "S")
                    {
                        Array.Sort(candys, (x, y) => x == null ? 1 : y == null ? -1 : x.Sort.CompareTo(y.Sort));
                        print_crate();
                    }
                    else if (val == "p" || val == "P")
                    {
                        Array.Sort(candys, (x, y) => x == null ? 1 : y == null ? -1 : x.Kostnad.CompareTo(y.Kostnad));
                        print_crate();
                    }
                    else if (val == "g" || val == "G")
                        Run();
                    else
                        sort_candys();      // vid inkorrekt inmatning hamnar man i menyn igen
                }
                public int check(string input) // Metod för att granska inmatning
                {
                    int korrektvärde;

                    try
                    {
                        korrektvärde = int.Parse(input);    // vid rätt inmatning skcikas talet tillbaka konverterat till int 
                        return korrektvärde;
                    }
                    catch
                    {
                        return korrektvärde = -1;
                    }
                }
            }
            class program
            {
                public static void Main(string[] args)    // Main metoden 
                {
                    Console.Clear();

                    var candycrate = new Candycrate();  // candycrate objekt bildas
                    candycrate.content_list();          // fyller listan med godis 
                    candycrate.Run();                   // anropar menyn
                }
            }
        }
    }
Laguna Online 30708
Postad: 9 aug 2021 20:23

Vad gör du när du testkör programmet? Vad matar du in, och när blir det stack overflow?

msoffer 27
Postad: 9 aug 2021 20:25
Laguna skrev:

Vad gör du när du testkör programmet? Vad matar du in, och när blir det stack overflow?

Jag trycker bara på den gröna knappen som finns i visual studio och de blir stack overflow direkt. 

Laguna Online 30708
Postad: 9 aug 2021 20:49

Det måste vara något fel i RecursiveBites. Jag ser inte vad, men prova att lusläsa den. 

Fermatrix 7841 – Fd. Medlem
Postad: 9 aug 2021 20:52

Jag hade definitivt debuggat och kollat vart exakt det kraschar. Eller ja, ger dig stack overflow. Inte kollat men om du använder rekursion någonstans är det förmodligen något småfel där.

msoffer 27
Postad: 9 aug 2021 20:53
Dracaena skrev:

Jag hade definitivt debuggat och kollat vart exakt det kraschar. Eller ja, ger dig stack overflow. Inte kollat men om du använder rekursion någonstans är det förmodligen något småfel där.

Hur gör man detta? :) 

msoffer 27
Postad: 9 aug 2021 20:53
Laguna skrev:

Det måste vara något fel i RecursiveBites. Jag ser inte vad, men prova att lusläsa den. 

känns som jag kollat igenom koderna 100 gånger idag men hittar ändå inte felet

Fermatrix 7841 – Fd. Medlem
Postad: 9 aug 2021 21:17

Vad använder du för IDE?

Yngve 40560 – Livehjälpare
Postad: 9 aug 2021 21:40
msoffer skrev:

Hur gör man detta? :) 

Om du inte kan köra koden i debugger och stega igenom så lan du lägga in spårutskrifter med relevant data på strategiska ställen så att du kan följa programmet "utifrån".

Laguna Online 30708
Postad: 10 aug 2021 06:57

RecursiveBites kanske är rätt, men den är svårbegriplig trots att den är så liten. Till att börja med skulle jag lägga in parenteser så det är helt klart vad som hör ihop, och dela upp den på flera rader. Jag stoppade in den i ett C-program, för jag har inte C#, och den returnerar helt enkelt 0 första gången, som den ska (det är troligt, men inte självklart, att ?: gör samma sak i C# som i C). Sedan blir den väl anropad först när du ger något kommando till programmet, och du säger att det kraschar innan dess.

Men om du stoppar in en spårutskrift i den (som första rad), så får vi se om det verkligen är där det blir fel.

Svara
Close