简体   繁体   English

“进程由于 StackOverflowException 而终止”,其原因在以下代码中

[英]"Process is terminating due to StackOverflowException", reason for it in the following code

A class which in it of itself contains its own object instantiated,when creating an object of that class in main method in c#, it gives stackoverflowExeption. class 本身包含自己的 object 实例化,当在 c# 的主要方法中创建 class 的 object 时,它会给出 stackoverflowExeption。 Why??为什么?? I want the reason for it, not the solution.Thanks我想要它的原因,而不是解决方案。谢谢

namespace project_1
{
class check
{
    check checkobject = new check();// Line-1

    /*I have not access Line-1 in main method.
     But due to Line-1 or Line-2, output says "Process is terminating due to StackOverflowException". Why??
     I do not need the solution, I want to know the reason for it.
     Removing " new check() " from Line-1, then it works fine.
     */
    public void Display() {
        Console.WriteLine("It worked");
    }
}
class DemoProgram
{
    static void Main(string[] args)
    {
        check ob1 = new check();// Line-2
        ob1.Display();
    }
}
}

This is because when you create a new check object from your main method, it triggers the initialization of the instance variable, checkobject , which again creates an object of class check.这是因为当您从 main 方法创建一个新的支票 object 时,它会触发实例变量checkobject的初始化,它再次创建一个 object 的 class 支票。 This is an infinite procedure, hence the memory alloted to your program is exhausted.这是一个无限过程,因此分配给您的程序的 memory 已用完。

You call your class constructor every time the class is initialised.每次初始化 class 时,您都会调用 class 构造函数。 The line marked as line 1 is the one you shouldn't have.标记为第 1 行的行是您不应该拥有的行。 It means you call your constructor recursively.这意味着你递归地调用你的构造函数。

If you try to debug your program, you see the similar output to the following.如果您尝试调试您的程序,您会看到类似于以下内容的 output。 If you know almost nothing why it happens, at least you can guess something is wrong subject to the constructor.如果你几乎不知道它为什么会发生,至少你可以猜测构造函数有问题。

Compilation succeeded - 1 warning(s)

jdoodle.cs(5,11): warning CS0414: The private field `check.checkobject' is assigned 
                  but its value is never used


Stack overflow: IP: 0x5647646e1705, fault addr: 0x7fffc422eff8
Stacktrace:
  at <unknown> <0xffffffff>
  at (wrapper alloc) object.AllocSmall (intptr,intptr) <0x00103>
  <...>
  at check..ctor () [0x00000] in <db1fd2bd96e041fab014c4ec28898e03>:0
  at check..ctor () [0x00000] in <db1fd2bd96e041fab014c4ec28898e03>:0
  at check..ctor () [0x00000] in <db1fd2bd96e041fab014c4ec28898e03>:0
  at check..ctor () [0x00000] in <db1fd2bd96e041fab014c4ec28898e03>:0
  at check..ctor () [0x00000] in <db1fd2bd96e041fab014c4ec28898e03>:0
  at check..ctor () [0x00000] in <db1fd2bd96e041fab014c4ec28898e03>:0
  at check..ctor () [0x00000] in <db1fd2bd96e041fab014c4ec28898e03>:0
  at check..ctor () [0x00000] in <db1fd2bd96e041fab014c4ec28898e03>:0
  ........
  ........
  ........
  ........
  ........
  at check..ctor () [0x00000] in <db1fd2bd96e041fab014c4ec28898e03>:0

  output Limit reached.

Your problem is an endless recursion caused by a field initializer .您的问题是由字段初始值设定项引起的无限递归

Example例子

public class Test
{
   Type FieldName = SomeValue;

A field initializer is executed before constructor bodies.字段初始值设定项在构造函数主体之前执行。 The important take-home point here is, they are always executed.这里重要的要点是,它们总是被执行。

Which means you can't do this, it runs when the class initialises.这意味着你不能这样做,它在class初始化时运行。

check checkobject = new check();

Every time you new up (initialise) this class , it's going to run the above code, which by its very nature new's up another instances of itself due to the *field initializers, which in-turns runs the above again so-on-and-so-forth until you run out of stack .每次你新建(初始化)这个class时,它都会运行上面的代码,由于 *field 初始值设定项,它的本质是 new 自身的另一个实例,它又依次运行上面的代码等等-so-forth直到你用完stack

If you really want a self-referencing property like this, and you want it initialised (in an automatic sense), use a lazy loading technique, eg.如果你真的想要一个像这样的自引用属性,并且你想要它初始化(在自动意义上),请使用延迟加载技术,例如。

private Check _checkObject;

public Check CheckObject => _checkObject?? (_checkObject = new Check());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM