Ошибка времени выполнения stackoverflowexception

I have a problem when use recursive method call.
I know the problem here setInfo(ref name, ref age, ref address, ref country);, but I don’t know how to fix it.

class person{
        private string name;
        private short age;
        private string address;
        private string country;

        public person(){
            Console.Write("Hi i'm constructor \n\n");
        }

        public void setInfo(ref string name, ref short age, ref string address, ref string country){
            if (name != "" || address != "" || country != "" || age != 0) {
                this.name = name;
                this.age = age;
                this.address = address;
                this.country = country;
            } else {
                setInfo(ref name, ref age, ref address, ref country); // Here is what I doubt.
            }
        }

        public void getInfo(){
            Console.Clear();
            Console.WriteLine("---- The information ----\nName: {0}\nAge: {1}\nAddress: {2}\nCountry: {3}", this.name, this.age, this.address, this.country);
        }

    }


// When usage


static void Main(string[] args){
            string name, address, country;
            short age; 

            person one = new person();

            Console.Write("Name: ");
            name = Console.ReadLine();

            Console.Write("Age: ");
            Int16.TryParse(Console.ReadLine(), out age);

            Console.Write("Address: ");
            address = Console.ReadLine();

            Console.Write("Country: ");
            country = Console.ReadLine();

            one.setInfo(ref name, ref age, ref address, ref country);
            one.getInfo();
        }

No Idea For Name's user avatar

asked Sep 17, 2013 at 11:49

Lion King's user avatar

4

in setInfo you check if the values are «» and if they are you call the method again without changing nothing.

in this case you call the setInfo over and over until the stack is full and then the exception is thrown

if you gonna call setInfo you need to change the values… or else you just stuck in an infinite calls to setInfo

for example, maybe give default values:

    public void setInfo(ref string name, ref short age, ref string address, ref string country){
            this.name    = name.Equals("")    == false? name : "abe";
            this.address = address.Equals("") == false ? address : "hevean";
            this.country = country.Equals("") == false ? country : "USA";
            this.age     = age > 0 ? age : 18;
    }

answered Sep 17, 2013 at 11:52

No Idea For Name's user avatar

No Idea For NameNo Idea For Name

11.4k10 gold badges43 silver badges71 bronze badges

2

Based on your code you don’t want to do recursion there.

You get the stack overflow because you make a recursive call without changing any data, which is what caused the recursive call in the first place. You need to allow the person to re-enter the missing data. Does that make sense?

Try wrapping your input with a do/while loop. This works:

    static void Main(string[] args)
    {
        string name, address, country;
        short age;

        person one = new person();

        do
        {
            Console.Write("Name: ");
            name = Console.ReadLine();

            Console.Write("Age: ");
            Int16.TryParse(Console.ReadLine(), out age);

            Console.Write("Address: ");
            address = Console.ReadLine();

            Console.Write("Country: ");
            country = Console.ReadLine();
        } while (name == "" || address == "" || country == "" || age < 1);

        one.setInfo(ref name, ref age, ref address, ref country);
        one.getInfo();

        Console.ReadKey();
    }

A couple points:

1) You might want to get rid of the ref’s since you are not changing any data in your setInfo. The only reason you would use ref is to return the changed values to the caller.

2) You should probably create a constructor that takes all four values and construct your person after you collect your data.

Hope that helps. Cheers.

answered Sep 17, 2013 at 12:06

CodeChops's user avatar

CodeChopsCodeChops

1,9801 gold badge20 silver badges27 bronze badges

0

Одна из самых распространенных ошибок, с которой разработчики программного обеспечения сталкиваются, — это исключение StackOverflowException. Это связано с ситуацией, когда приложение потребляет всю доступную область памяти в стеке вызовов, из-за чего выполняющийся процесс прекращается. В этой статье мы рассмотрим, что это за ошибка, почему она возникает и как ее исправить.

## Что такое StackOverflowException?
StackOverflowException — это исключение, которое возникает во время выполнения программы, когда память, выделенная в стеке для вызовов функций, исчерпывается. Каждая функция, вызванная в вашей программе, помещает указатель на стек вызовов, который содержит информацию о вызываемой функции, параметрах функции и адресе возврата. Когда функция завершается, указатель возвращается к предыдущей функции в стеке.

Когда функция вызывается слишком много раз, стек вызовов заполняется и может привести к StackOverflowException. Такая ситуация может быть вызвана несколькими факторами, включая рекурсивные вызовы без базового случая, бесконечные циклы или большой объем данных передаваемых с использованием стека.

## Почему возникает ошибка StackOverflowException?
Ошибки StackOverflowException могут возникать по нескольким причинам, включая следущие:

1. Рекурсивные вызовы без базового случая: Рекурсия — это процесс, когда функция вызывает саму себя. Если в вашей рекурсивной функции отсутствует базовый случай или он недостаточно точно определен, то функция будет выполняться до тех пор, пока не будет достигнут предел глубины стека вызовов.

2. Бесконечные циклы: Если ваша программа содержит бесконечный цикл, то он будет продолжаться, пока не будет исчерпана память в стеке вызовов. Например, если у вас есть цикл, который всегда выполняется, пока истина, и вы забыли изменить условие, то он будет выполняться бесконечно и приведет к StackOverflowException.

3. Большой объем данных передаваемых с использованием стека: Стек вызовов имеет ограниченный объем памяти, и если вы передаете большой объем данных с использованием стека, это может привести к его переполнению. Например, если вы передаете массив данных через каждый вызов рекурсивной функции, то это может привести к StackOverflowException.

## Как исправить ошибку StackOverflowException?

1. Проверьте рекурсивные вызовы: Если ваша программа содержит рекурсивные вызовы, убедитесь, что у них есть базовый случай, который ограничивает глубину рекурсии. Базовый случай должен быть достижимым и должен привести к завершению рекурсии. Проанализируйте код и убедитесь, что рекурсивные вызовы ограничены определенным условием.

2. Избегайте бесконечных циклов: При написании циклов убедитесь, что вы указали правильное условие завершения цикла. Убедитесь, что выполняющийся код в цикле меняет условие, чтобы цикл завершился. Если ваш цикл предназначен для бесконечного выполнения, то убедитесь, что в нем есть приведение к спящему режиму (например, использование функции sleep()), чтобы другие процессы имели возможность обрабатываться и не вызывали переполнение стека вызовов.

3. Используйте другие методы передачи данных: Если вы передаете большой объем данных через вызовы функций или рекурсию, попробуйте использовать другие методы передачи данных, такие как передача данных через аргументы функций, глобальные переменные или структуры данных. Это поможет снизить использование памяти стека и предотвратить переполнение стека вызовов.

4. Увеличьте размер стека вызовов: Для некоторых случаев, когда обработка большого объема данных или рекурсивные вызовы неизбежны, вы можете изменить параметры конфигурации вашей среды выполнения (например, изменить параметр stack size) для увеличения размера стека вызовов. Это может быть полезно, но имейте в виду, что увеличение размера стека может повлечь другие последствия, такие как увеличение потребления памяти.

5. Реализуйте оптимизацию кода: Часто переполнение стека вызовов имеет место из-за неоптимального кода, который вызывает множество рекурсивных вызовов или выполняет бесконечные циклы. Проведите анализ вашего кода и примените оптимизации, чтобы улучшить производительность и уменьшить использование памяти стека вызовов.

В итоге, ошибка StackOverflowException является распространенной и часто встречающейся ошибкой программирования. Это происходит, когда область памяти стека вызовов переполняется из-за рекурсивных вызовов без базового случая, бесконечных циклов или большого объема данных передаваемых с использованием стека. Она может быть исправлена путем добавления базового случая в рекурсивные вызовы, устранения бесконечных циклов, использования других методов передачи данных, увеличения размера стека вызовов или применения оптимизации кода.

Форум мехмата ЮФУ

Загрузка…

здравствуйте.
Выходит ошибка «Ошибка времени выполнения: StackOverflowException: Программа завершена из-за переполнения программного стека». В чем ошибка, не пойму.

Вот задача
(Е. Джобс) Алгоритм вычисления функции F(n), где n – натуральное число, задан следующими соотношениями:
F(n) = n + 1 при n < 3,
F(n) = n + 2*F(n + 2), когда n ≥ 3 и четно,
F(n) = F(n – 2) + n – 2, когда n ≥ 3 и нечетно.
Сколько существует чисел n, для которых значение F(n) будет трехзначным.
Ответ известен : 22

Ниже мой проект программы:
//Функция F
function F(n: integer): integer;
begin
if n < 3 then
F := n + 1
else
if ((n mod 2) = 0) then
F := n + 2 * F(n + 2)
else
F := F(n — 2) + n — 2;
end;

var
cikl, kolvo: integer;
//Основная часть программы, где запускаем функцию.
begin
kolvo := 0;
for cikl := 1 to 100 do
begin
if (F(cikl) >= 100) and (F(cikl) <= 999) then
kolvo := kolvo + 1;
end;

WriteLn(cikl);
end.

This is difficult situation to explain. Have a service process that starts 2 threads, each thread loops forever but sleeps for 5 minutes each once the payload is finished.

Problem is that my second thread terminates well before the payload is even finished, for no apparent reason, and i also can’t catch the exception as it seems to be triggered from outside the delegate process?

Any suggestions on how to find the problem?

The code….

public void StartService()
{
  ThreadStart stRecieve = new ThreadStart(DownloadNewMail);
  ThreadStart stSend = new ThreadStart(SendNewMail);
  senderThread = new Thread(stRecieve);
  recieverThread = new Thread(stSend);

  sendStarted = true;
  recieveStarted = true;

  senderThread.Start();
  recieverThread.Start();
}

private void DownloadNewMail()
{
  while(recieveStarted)
  {
    //Payload....

    if (recieveStarted)
    {
      Thread.Sleep(new TimeSpan(0, confSettings.PollInterval, 0));
    }
  }
}

private void SendNewMail()
{
  while(sendStarted)
  {
    //Payload....

    if (sendStarted)
    {
      Thread.Sleep(new TimeSpan(0, confSettings.PollInterval, 0));
    }
  }

}

asked Dec 15, 2010 at 11:10

Jan de Jager's user avatar

Jan de JagerJan de Jager

8702 gold badges13 silver badges35 bronze badges

6

Try to check callstack lenght in your code:

class Program
{
    static void Main(string[] args)
    {
        try
        {
            Hop();
        }
        catch (Exception e)
        {
            Console.WriteLine("Exception - {0}", e);
        }
    }

    static void Hop()
    {
        CheckStackTrace();
        Hip();
    }

    static void Hip()
    {
        CheckStackTrace();
        Hop();
    }

    static void CheckStackTrace()
    {
        StackTrace s = new StackTrace();
        if (s.FrameCount > 50)
            throw new Exception("Big stack!!!!");
    }
}

answered Dec 15, 2010 at 12:09

acoolaum's user avatar

acoolaumacoolaum

2,1322 gold badges15 silver badges24 bronze badges

If you are having trouble following the flow of your application’s code execution, try logging the entrance of methods with a timestamp and threadid.

Also, You can’t catch the exception because it is a StackOverflowException.

See msdn: «Starting with the .NET Framework version 2.0, a StackOverflowException object cannot be caught by a try-catch block and the corresponding process is terminated by default. Consequently, users are advised to write their code to detect and prevent a stack overflow. For example, if your application depends on recursion, use a counter or a state condition to terminate the recursive loop. «

answered Dec 15, 2010 at 11:25

Eric Dahlvang's user avatar

Eric DahlvangEric Dahlvang

8,2524 gold badges29 silver badges50 bronze badges

1

Do you utlize any heavy-weight library for tasks like DownloadNewMail and SendNewMail? For example I encountered StackOverflows when running large jobs using Microsoft.SqlServer.Dts.Runtime.Package. Try running the same workload sequentially inside a command-line application to see if the issue persists.

answered Dec 15, 2010 at 12:28

Oleg Zhylin's user avatar

Oleg ZhylinOleg Zhylin

1,29012 silver badges18 bronze badges

1

Понравилась статья? Поделить с друзьями:
  • Ошибка времени выполнения basic объектная переменная не установлена
  • Ошибка времени выполнения basic аргумент является обязательным
  • Ошибка времени выполнения basic openoffice
  • Ошибка вызова сервиса лицензирования
  • Ошибка вызова сервиса передачи получения данных дублирование данных