【问题标题】:"Process is terminating due to StackOverflowException", reason for it in the following code“进程因 StackOverflowException 而终止”,原因如下代码
【发布时间】:2020-02-24 05:18:20
【问题描述】:

一个类,它本身包含它自己的实例化对象,当在 c# 的 main 方法中创建该类的对象时,它会给出 stackoverflowExeption。为什么??我想要它的原因,而不是解决方案。谢谢

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();
    }
}
}

【问题讨论】:

  • 您正在递归地实例化该类,因此您的堆栈内存不足。看看这个答案:stackoverflow.com/a/34182621/10531996
  • 问题在于它正在无限地创建越来越多的实例

标签: c# stack-overflow


【解决方案1】:

这是因为当您从 main 方法创建一个新的检查对象时,它会触发实例变量 checkobject 的初始化,这会再次创建一个类检查对象。这是一个无限过程,因此分配给您的程序的内存已用完。

【讨论】:

  • @PrakharLondhe 他不能赞成答案,但他可以接受。
  • @dan1st 哦,好吧,我忘记了特权:P
  • 接受会给你带来更多的声誉:)
【解决方案2】:

每次初始化类时都会调用类构造函数。标记为第 1 行的行是您不应该拥有的行。这意味着你递归地调用你的构造函数。

【讨论】:

    【解决方案3】:

    如果您尝试debug 您的程序,您会看到与以下类似的输出。如果你几乎不知道它发生的原因,至少你可以猜到构造函数有问题。

    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.
    

    【讨论】:

      【解决方案4】:

      您的问题是由 字段初始值设定项引起的无限递归。

      示例

      public class Test
      {
         Type FieldName = SomeValue;
      

      字段初始化器在构造函数体之前执行。这里重要的一点是,它们总是被执行。

      这意味着您不能这样做,它会在 类 初始化时运行。

      check checkobject = new check();
      

      每次你new up(初始化)这个class,它都会运行上面的代码,就其本质而言,new 会创建另一个自身的实例,因为*field 初始化器,它会再次运行上述操作 so-on-and-so-forth,直到您用完 stack。

      如果您真的想要这样的 自引用 属性,并且希望它初始化(在自动意义上),请使用延迟加载技术,例如。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-01-04
        • 1970-01-01
        • 2020-11-02
        • 1970-01-01
        • 2018-09-06
        • 2014-11-18
        • 1970-01-01
        相关资源
        最近更新 更多