Stack overflow in the following program

0

you will see, we have a project for class in which we have to work with functions and there are different functions for each utility of the program, convert from binary to decimal, hexadecimal ... etc. The fact is that the functions correctly do the conversion and such, but when you get to the same loop that makes them, I throw stack overflow error, and I do not have much idea why, I leave the code I have done so far, to see if can someone give me an orientation:

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

namespace UF2PR2Solucio
{
    class Program
    {
        static void Main(string[] args)
        {
            int opcio = 0;
            bool acabar = false;

            while (!acabar)
            {
                Console.Clear();
                opcio = menuPrincipal();
                switch (opcio)
                {
                    case 1:
                        decimalBinari();
                        break;
                    case 2:
                        binariDecimal();
                        break;
                    case 3:
                        decimalHexadecimal();
                        break;
                    case 4:
                        HexadecimalDecimal();
                        break;
                    case 5:
                        binariHexadecimal();
                        break;
                    case 6:
                        hexadecimalBinari();
                        break;
                    case 7:
                        qualsevol();
                        break;
                    case 8:
                        ajuda();
                        break;
                    case 9:
                        acabar = true;
                        break;
                    default:
                        Console.WriteLine("\nEsperava un numero de l'u al 9");
                        break;
                }
                if (!acabar) espera();
            }
        }
        public static void decimalBinari()
        {
            String numero;

            Console.WriteLine("Entra un numero decimal: ");
            numero = Console.ReadLine();
            //Comprovacio base
            if (esBase(10, numero)) Console.WriteLine(Conversio(10, 2, numero));
            else Console.WriteLine("Esperava un numero decimal");
        }
        public static void binariDecimal()
        {
            String numero;

            Console.WriteLine("Entra un numero binari: ");
            numero = Console.ReadLine();
            //Comprovacio base
            if (esBase(2, numero)) Console.WriteLine(Conversio(2, 10, numero));
            else Console.WriteLine("Esperava un numero binari");
        }
        public static void HexadecimalDecimal()
        {
            String numero;

            Console.WriteLine("Entra un numero hexadecimal: ");
            numero = Console.ReadLine();
            //Comprovacio base
            if (esBase(16, numero)) Console.WriteLine(convertirABaseDeu(16, numero));
            else Console.WriteLine("Esperava un numero hexadecimal");
        }
        public static void decimalHexadecimal()
        {
            String numero;

            Console.WriteLine("Entra un numero decimal: ");
            numero = Console.ReadLine();
            //Comprovacio base
            if (esBase(10, numero)) Console.WriteLine(Conversio(10, 16, numero));
            else Console.WriteLine("Esperava un numero decimal");
        }


        public static void binariHexadecimal()
        {
            String numero;

            Console.WriteLine("Entra un numero decimal: ");
            numero = Console.ReadLine();
            //Comprovacio base
            if (esBase(10, numero)) Console.WriteLine(Conversio(2, 16, numero));
            else Console.WriteLine("Esperava un numero binari");
        }


        public static void hexadecimalBinari()
        {
            String numero;

            Console.WriteLine("Entra un numero decimal: ");
            numero = Console.ReadLine();
            //Comprovacio base
            if (esBase(10, numero)) Console.WriteLine(Conversio(16, 2, numero));
            else Console.WriteLine("Esperava un numero hexadecimal");
        }


        public static void qualsevol()
        {//menu 7
            String numero;
            int baseInicial, baseDesti;

            Console.WriteLine("Entra un numero: ");
            numero = Console.ReadLine();
            Console.WriteLine("Entra la base en que esta aquest nombre: ");
            baseInicial = int.Parse(Console.ReadLine());
            Console.WriteLine("Entra la base a la que el vols convertir: ");
            baseDesti = int.Parse(Console.ReadLine());
            //Comprovacio base
            if (esBase(baseInicial, numero)) Console.WriteLine(Conversio(baseInicial, baseDesti, numero));
            else Console.WriteLine("El nombre introduit no és de la base especificada");
        }
        public static String Conversio(int baseInicial, int baseDesti, String Numero)
        {
            String resultat;
            int resultatB10;
            //Primer convertim de base inicial a base 10
            resultatB10 = convertirABaseDeu(baseInicial, Numero);
            //Despres convertim de base 10 a base desti
            resultat = convertirDeBaseDeu(resultatB10, baseDesti);
            return "hola soc la funcio conversio";
        }
        public static String convertirDeBaseDeu(int numero, int baseDesti)
        {

            String resultat = Conversio(10, baseDesti, numero.ToString());

            //Comprovacio base
            if (esBase(10, numero.ToString())) Console.WriteLine(Conversio(10, baseDesti, numero.ToString()));
            else Console.WriteLine("Esperava un numero en base 10");

            return resultat;
        }
        public static int convertirABaseDeu(int baseNum, String numero)
        {
            int resultat = 0;
            int llargada;
            int digit;
            int potencia = 0;

            llargada = numero.Length;
            for (int x = llargada - 1; x >= 0; x--)
            {
                digit = (int)Char.GetNumericValue(numero[x]);
                if (digit == -1) digit = Convert.ToInt32(numero[x]) - 55;

                resultat = resultat + (digit * Convert.ToInt32(Math.Pow(baseNum, potencia)));
                potencia++;
            }

            Console.WriteLine("el valor a en decimal es : " + resultat);
            return resultat;
        }

        public static Boolean esBase(int laBase, String numero)
        {
            bool resultat = true;

            foreach (char digit in numero)
            {
                if (!digitPertanyBase(digit, laBase))
                {
                    resultat = false;
                    break;
                }
            }
            return resultat;
        }
        public static Boolean digitPertanyBase(char digit, int baseNum)
        {
            bool trobat = false;
            char[] simbols = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
            int x = 0;
            do
            {
                if (digit == simbols[x]) trobat = true;
                x++;
            }
            while ((x < baseNum) && (!trobat));
            return trobat;
        }

        public static int menuPrincipal()
        {
            int opcio = 0;
            ConsoleKeyInfo cki;

            escriureMenu();
            cki = Console.ReadKey(true);
            if (Char.IsNumber(cki.KeyChar))
                opcio = Int32.Parse(cki.KeyChar.ToString());
            else opcio = 0;

            return opcio;
        }
        public static void escriureMenu()
        {
            Console.WriteLine("-----------------------------");
            Console.WriteLine("Conversió de bases numèriques");
            Console.WriteLine("-----------------------------");
            Console.WriteLine("1 - Decimal a binari");
            Console.WriteLine("2 - Binari a decimal");
            Console.WriteLine("3 - Decimal a hexadecimal");
            Console.WriteLine("4 - Hexadecimal a decimal");
            Console.WriteLine("5 - Binari a hexadecimal");
            Console.WriteLine("6 - Hexadecimal a binari");
            Console.WriteLine("7 - D'una base a qualsevol altra");
            Console.WriteLine("8 - Ajuda");
            Console.WriteLine("9 - Sortir");
        }
        public static void ajuda()
        {
            Console.Clear();
            Console.WriteLine("Si saps que són les bases numèriques, no et cal gaire ajuda");
            Console.WriteLine("Si tens alguna queixa, pots escriure-la i,quan premis ENTER serà enviada al nostres programadors");

        }



        public static void espera()
        {
            Console.WriteLine("Prem ANY KEY per tornar al menu");
            Console.ReadLine();
        }
    }


}

Thank you very much in advance to all! In the meantime, I'm going to continue to check the code, to see if I can find anything.

    
asked by THR4SH3RP0L0 24.02.2017 в 20:43
source

1 answer

3

Breakpoints and exploring the code step by step are your best friends in this case.

In this function, what happens is that you call the code:

convertirABaseDeu(baseInicial, Numero);

which jumps to:

public static int convertirABaseDeu(int baseNum, String numero)

When finishing this function the previous function summarizes its execution and arrives at:

resultat = convertirDeBaseDeu(resultatB10, baseDesti);

Which executes:

public static String convertirDeBaseDeu(int numero, int baseDesti)
        {

            String resultat = Conversio(10, baseDesti, numero.ToString());

            //Comprovacio base
            if (esBase(10, numero.ToString())) Console.WriteLine(Conversio(10, baseDesti, numero.ToString()));
            else Console.WriteLine("Esperava un numero en base 10");

            return resultat;
        }

When you reach the line:

 String resultat = Conversio(10, baseDesti, numero.ToString());

You create a new call to the function when you call it back when it has not yet finished in the previous execution:

public static String Conversio(int baseInicial, int baseDesti, String Numero)

Which generates you that these functions are calling infinitely in a cycle from which you can not exit. In the call stack we can see the behavior of the jumps between both mentioned functions:

The call stack after 4 iterations:

The call stack after 6 iterations:

The function:

public static String Conversio(int baseInicial, int baseDesti, String Numero)

Keep accumulating in the call stack until it overflows and gives you the StackOverflow error

Note: I suspect that there is another similar function in the other conversion cases where you get stuck in infinite calls between two functions.

    
answered by 24.02.2017 / 21:51
source