• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

Simple class with self-referencing member fail to run: StackOverflowException

  • Thread starter pedestrian via DotNetMonster.com
  • Start date
P

pedestrian via DotNetMonster.com

#1
I get this from a book on C#. I tried to compile and run it but it throw
StackOverflowException.
What is wrong with the self-referencing member?

Thanks a lot! :)

class Tire
{
public const Tire GoodStone = new Tire(90);
public const Tire FireYear = new Tire(100);

public int manufactureID;
public Tire()
{
Console.WriteLine("Default ctor of Tire.");
}
public Tire(int ID)
{
Console.WriteLine("Custom ctor of Tire...");
manufactureID = ID;
}
}

class Program
{
static void Main(string[] args)
{
Tire t = new Tire();

Console.ReadLine();
}
}

--
Warmest Regards,
Pedestrian

Message posted via DotNetMonster.com
http://www.dotnetmonster.com/Uwe/Forums.aspx/dotnet-general/200811/1
 

My Computer

F

Family Tree Mike

#2
"pedestrian via DotNetMonster.com" <u16758@xxxxxx> wrote in message
news:8dcd38cf3ca82@xxxxxx

>I get this from a book on C#. I tried to compile and run it but it throw
> StackOverflowException.
> What is wrong with the self-referencing member?
>
> Thanks a lot! :)
>
> class Tire
> {
> public const Tire GoodStone = new Tire(90);
> public const Tire FireYear = new Tire(100);
>
> public int manufactureID;
> public Tire()
> {
> Console.WriteLine("Default ctor of Tire.");
> }
> public Tire(int ID)
> {
> Console.WriteLine("Custom ctor of Tire...");
> manufactureID = ID;
> }
> }
>
> class Program
> {
> static void Main(string[] args)
> {
> Tire t = new Tire();
>
> Console.ReadLine();
> }
> }
>
> --
> Warmest Regards,
> Pedestrian
>
> Message posted via DotNetMonster.com
> http://www.dotnetmonster.com/Uwe/Forums.aspx/dotnet-general/200811/1
>

I'm guessing you copied something incorrectly.

Each call to the default or custom ctor in this class creates three
instances, the one requested, plus FireYear and GoodStone. The problem is
that the extra two instances then create three instances, each ad nauseum.

Not knowing what the original text was showing, I cannot recommend how to
change it other than don't create the FireYear and GoodStone objects in the
tire class.

Lastly, perhaps this works in other versions of .Net, but in VS 2008/C# 3.0,
you cannot declare the following:

public const Tire FireYear = new Tire(90);

Objects cannot be constant.

Mike
 

My Computer

P

pedestrian via DotNetMonster.com

#3
Oops I place the wrong code for the question,
you are right, constant cannot be objects... Thanks!

What I mean should be readonly instead of const:

The following still don't work unless there are declared as static readonly...

any explanation ?

Thanks...

class Tire
{
public readonly Tire GoodStone = new Tire(90);
public readonly Tire FireYear = new Tire(100);

public int manufactureID;
public Tire()
{
Console.WriteLine("Default ctor of Tire.");
}
public Tire(int ID)
{
Console.WriteLine("Custom ctor of Tire...");
manufactureID = ID;
}
}

class Program
{
static void Main(string[] args)
{
Tire t = new Tire();

Console.ReadLine();
}
}



Family Tree Mike wrote:

>>I get this from a book on C#. I tried to compile and run it but it throw
>> StackOverflowException.
>[quoted text clipped - 28 lines]

>> }
>> }
>
>I'm guessing you copied something incorrectly.
>
>Each call to the default or custom ctor in this class creates three
>instances, the one requested, plus FireYear and GoodStone. The problem is
>that the extra two instances then create three instances, each ad nauseum.
>
>Not knowing what the original text was showing, I cannot recommend how to
>change it other than don't create the FireYear and GoodStone objects in the
>tire class.
>
>Lastly, perhaps this works in other versions of .Net, but in VS 2008/C# 3.0,
>you cannot declare the following:
>
>public const Tire FireYear = new Tire(90);
>
>Objects cannot be constant.
>
>Mike
--
Warmest Regards,
Pedestrian

Message posted via DotNetMonster.com
http://www.dotnetmonster.com/Uwe/Forums.aspx/dotnet-general/200811/1
 

My Computer

F

Family Tree Mike

#4
"pedestrian via DotNetMonster.com" <u16758@xxxxxx> wrote in message
news:8dd19ae30ec54@xxxxxx

> Oops I place the wrong code for the question,
> you are right, constant cannot be objects... Thanks!
>
> What I mean should be readonly instead of const:
>
> The following still don't work unless there are declared as static
> readonly...
>
> any explanation ?
>
> Thanks...
By making the FireYear and GoodStone objects static, there is no creation of
them each call to either of the constructors. This means that when you call
the constructor, there is only one instance created, as a static member is
created for the class, not for each instance. This is why the stack
overflow does not happen, as you have eliminated the recursion issue.

Mike
 

My Computer

P

pedestrian via DotNetMonster.com

#5
Yes.... that's the reason static fields works....

however, about the recursion part, it seems that the constructors
were not called, at least I didn't notice that since the Console.WriteLine
statement never show the results....

Family Tree Mike wrote:

>> Oops I place the wrong code for the question,
>> you are right, constant cannot be objects... Thanks!
>[quoted text clipped - 7 lines]

>>
>> Thanks...
>
>By making the FireYear and GoodStone objects static, there is no creation of
>them each call to either of the constructors. This means that when you call
>the constructor, there is only one instance created, as a static member is
>created for the class, not for each instance. This is why the stack
>overflow does not happen, as you have eliminated the recursion issue.
>
>Mike
--
Warmest Regards,
Pedestrian

Message posted via DotNetMonster.com
http://www.dotnetmonster.com/Uwe/Forums.aspx/dotnet-general/200811/1
 

My Computer

F

Family Tree Mike

#6
"pedestrian via DotNetMonster.com" <u16758@xxxxxx> wrote in message
news:8dd76d86cdc35@xxxxxx

> Yes.... that's the reason static fields works....
>
> however, about the recursion part, it seems that the constructors
> were not called, at least I didn't notice that since the Console.WriteLine
> statement never show the results....
>
> Family Tree Mike wrote:

>>> Oops I place the wrong code for the question,
>>> you are right, constant cannot be objects... Thanks!
>>[quoted text clipped - 7 lines]

>>>
>>> Thanks...
>>
>>By making the FireYear and GoodStone objects static, there is no creation
>>of
>>them each call to either of the constructors. This means that when you
>>call
>>the constructor, there is only one instance created, as a static member is
>>created for the class, not for each instance. This is why the stack
>>overflow does not happen, as you have eliminated the recursion issue.
>>
>>Mike
>
> --
> Warmest Regards,
> Pedestrian
>
> Message posted via DotNetMonster.com
> http://www.dotnetmonster.com/Uwe/Forums.aspx/dotnet-general/200811/1
>

Fields are initialized before the constructor code executes. That causes
the recursion with no output.

--
Mike
 

My Computer

P

pedestrian via DotNetMonster.com

#7
Yes, fields are initialized first...

however, I expect after that the constructor being executed....
then only the next recursion level fields being initialized, then the
ctor called,
then further next recursion level fields being initialized, then
the ctor called....

I suppose in this case, the constructor should at least been called for
plenty of times before stack overflow exception...

Thanks for replying...

Family Tree Mike wrote:

>
>Fields are initialized before the constructor code executes. That causes
>the recursion with no output.
>
--
Warmest Regards,
Pedestrian

Message posted via http://www.dotnetmonster.com
 

My Computer

J

Jack Jackson

#8
The first instantiation of a Tire attempts to create a new Tire for
GoodStone. The creation of that Tire attempts to create a new Tire
for its Goodstone. The creation of that Tire attempts to create a new
Tire for its Goodstone.

You can see where this is going. It never gets past initializing
Goodstone in any instance.

On Fri, 28 Nov 2008 03:39:35 GMT, "pedestrian via DotNetMonster.com"
<u16758@xxxxxx> wrote:

>Yes, fields are initialized first...
>
>however, I expect after that the constructor being executed....
> then only the next recursion level fields being initialized, then the
>ctor called,
> then further next recursion level fields being initialized, then
>the ctor called....
>
>I suppose in this case, the constructor should at least been called for
>plenty of times before stack overflow exception...
>
>Thanks for replying...
>
>Family Tree Mike wrote:

>>
>>Fields are initialized before the constructor code executes. That causes
>>the recursion with no output.
>>
 

My Computer

P

pedestrian via DotNetMonster.com

#9
Why is the instantiation of a Tire and subsequent Tire instantiation
didn't call the constructor? I never see the Console.WriteLine text being
showed...

I appreciate your explanation.

Jack Jackson wrote:

>The first instantiation of a Tire attempts to create a new Tire for
>GoodStone. The creation of that Tire attempts to create a new Tire
>for its Goodstone. The creation of that Tire attempts to create a new
>Tire for its Goodstone.
>
>You can see where this is going. It never gets past initializing
>Goodstone in any instance.
>

>>Yes, fields are initialized first...
>>
>[quoted text clipped - 11 lines]

>>>Fields are initialized before the constructor code executes. That causes
>>>the recursion with no output.
--
Warmest Regards,
Pedestrian

Message posted via DotNetMonster.com
http://www.dotnetmonster.com/Uwe/Forums.aspx/dotnet-general/200811/1
 

My Computer

F

Family Tree Mike

#10
"pedestrian via DotNetMonster.com" <u16758@xxxxxx> wrote in message
news:8de5f97050c76@xxxxxx

> Why is the instantiation of a Tire and subsequent Tire instantiation
> didn't call the constructor? I never see the Console.WriteLine text being
> showed...
>
> I appreciate your explanation.
>
> Jack Jackson wrote:

>>The first instantiation of a Tire attempts to create a new Tire for
>>GoodStone. The creation of that Tire attempts to create a new Tire
>>for its Goodstone. The creation of that Tire attempts to create a new
>>Tire for its Goodstone.
>>
>>You can see where this is going. It never gets past initializing
>>Goodstone in any instance.
>>

>>>Yes, fields are initialized first...
>>>
>>[quoted text clipped - 11 lines]

>>>>Fields are initialized before the constructor code executes. That
>>>>causes
>>>>the recursion with no output.
>
> --
> Warmest Regards,
> Pedestrian
>
> Message posted via DotNetMonster.com
> http://www.dotnetmonster.com/Uwe/Forums.aspx/dotnet-general/200811/1
>
It never gets to the constructor code in any instance because EVERY instance
that is created is creating two new instances before the constructor is
called. There is no end condition to the "preconstructor" events in any of
the objects. I'm not sure that preconstructor is the right word, but it
basically means the initialization of all the members such as GoodStone and
FireYear.

Cycle 1: instance, field1 (GoodStone), field2 (FireYear)
Cycle 2: field11, field12, field21, field22
Cycle 3: field111, field112, field121, field122, field211,
field212, field221, field222
and so on...

The original instance constructor (Cycle 1 instance) never executs until all
the cycles are done. Obviously that won't happen.

Worse yet, the subsequent constructors (field1, field111, etc...) will not
execute until the end of the recursion.

Hope this helps...

--
Mike
 

My Computer

J

Jack Jackson

#11
When Instance #1 is instantiatied, the first thing that happens is the
fields are initialized. The first field (GoodStone) creates another
instance of Tire, call that Instance #2.

Instance #2 starts to intialize its fields. The first field,
GoodStone, creates another instance of Tire, call that Instance #3.

Instance #3 starts to initialize its fields. The first field,
Goodstone, creates another instance of Tire, call that Instance #4.

And so on, until all memory is exhausted. All of this occurs in one
thread of execution, so no instance of Tire ever gets past the
initialization of the GoodStone field.

If you set a breakpoint on the initialization of the second field you
should see that it never gets executed.

On Sat, 29 Nov 2008 05:43:21 GMT, "pedestrian via DotNetMonster.com"
<u16758@xxxxxx> wrote:

>Why is the instantiation of a Tire and subsequent Tire instantiation
>didn't call the constructor? I never see the Console.WriteLine text being
>showed...
>
>I appreciate your explanation.
>
>Jack Jackson wrote:

>>The first instantiation of a Tire attempts to create a new Tire for
>>GoodStone. The creation of that Tire attempts to create a new Tire
>>for its Goodstone. The creation of that Tire attempts to create a new
>>Tire for its Goodstone.
>>
>>You can see where this is going. It never gets past initializing
>>Goodstone in any instance.
>>

>>>Yes, fields are initialized first...
>>>
>>[quoted text clipped - 11 lines]

>>>>Fields are initialized before the constructor code executes. That causes
>>>>the recursion with no output.
 

My Computer

F

Family Tree Mike

#12
"Jack Jackson" <jjackson@xxxxxx> wrote in message
news:sf13j4homrv0sekjkcidvo6trksp29apcn@xxxxxx

> When Instance #1 is instantiatied, the first thing that happens is the
> fields are initialized. The first field (GoodStone) creates another
> instance of Tire, call that Instance #2.
>
> Instance #2 starts to intialize its fields. The first field,
> GoodStone, creates another instance of Tire, call that Instance #3.
>
> Instance #3 starts to initialize its fields. The first field,
> Goodstone, creates another instance of Tire, call that Instance #4.
>
> And so on, until all memory is exhausted. All of this occurs in one
> thread of execution, so no instance of Tire ever gets past the
> initialization of the GoodStone field.
>
> If you set a breakpoint on the initialization of the second field you
> should see that it never gets executed.
>
> On Sat, 29 Nov 2008 05:43:21 GMT, "pedestrian via DotNetMonster.com"
> <u16758@xxxxxx> wrote:
>

>>Why is the instantiation of a Tire and subsequent Tire instantiation
>>didn't call the constructor? I never see the Console.WriteLine text being
>>showed...
>>
>>I appreciate your explanation.
>>
>>Jack Jackson wrote:

>>>The first instantiation of a Tire attempts to create a new Tire for
>>>GoodStone. The creation of that Tire attempts to create a new Tire
>>>for its Goodstone. The creation of that Tire attempts to create a new
>>>Tire for its Goodstone.
>>>
>>>You can see where this is going. It never gets past initializing
>>>Goodstone in any instance.
>>>
>>>>Yes, fields are initialized first...
>>>>
>>>[quoted text clipped - 11 lines]
>>>>>Fields are initialized before the constructor code executes. That
>>>>>causes
>>>>>the recursion with no output.

Oh, you are right, the second field never gets started. Thanks!

--
Mike
 

My Computer

P

pedestrian via DotNetMonster.com

#13
Thanks for the clear explanation... Jack.

Thanks to Mike too....

Jack Jackson wrote:

>When Instance #1 is instantiatied, the first thing that happens is the
>fields are initialized. The first field (GoodStone) creates another
>instance of Tire, call that Instance #2.
>
>Instance #2 starts to intialize its fields. The first field,
>GoodStone, creates another instance of Tire, call that Instance #3.
>
>Instance #3 starts to initialize its fields. The first field,
>Goodstone, creates another instance of Tire, call that Instance #4.
>
>And so on, until all memory is exhausted. All of this occurs in one
>thread of execution, so no instance of Tire ever gets past the
>initialization of the GoodStone field.
>
>If you set a breakpoint on the initialization of the second field you
>should see that it never gets executed.
>

>>Why is the instantiation of a Tire and subsequent Tire instantiation
>>didn't call the constructor? I never see the Console.WriteLine text being
>[quoted text clipped - 15 lines]

>>>>>Fields are initialized before the constructor code executes. That causes
>>>>>the recursion with no output.
--
Warmest Regards,
Pedestrian

Message posted via DotNetMonster.com
http://www.dotnetmonster.com/Uwe/Forums.aspx/dotnet-general/200812/1
 

My Computer

Users Who Are Viewing This Thread (Users: 1, Guests: 0)