473,406 Members | 2,451 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

managed (/clr) destructors

I would assume in the following that 'instance' being set to 'nullptr'
should cause the instance of myClass that was created to no longer have any
pointers pointing to it, and therefore be 'destroyed':

ref myClass
{
public:
myClass() {}
~myClass() {} // never called
!myClass() {} // never called
} ;

main()
{
myClass^ instance = gcnew myClass() ;
instance = nullptr ; // shouldn't this cause destruction?
}

However, as indicated, neither the destructor or finalizer get called when
'instance' is set to 'nullptr'. Is the object previously pointed to by
'instance' still around (.e., it still has memory resources)? Isn't having
all existing pointers to an object either being set to nullptr or going out
of scope cause the object to be destructed? If not, what am I missing here?
If so, why is neither the destructor or finalizer called?

For context, using VS C++.NET 2005 Express in /clr mode, I'm trying to count
(using a static class variable) the number of existing instances of myClass.
It is easy to count the creations (bump counter in each constructor), but
how do I count the destructions?

thanks in advance for responses! : )

[==P==]
Nov 17 '05 #1
9 1316
JAL
Peter... When a managed class is no longer reachable from root it is eligible
for garbage collection. You can force the garbage collector just as a test
case to force the call to Finalize. In your example you are not using stack
based semantics so the destructor will not be called. I wrote an artice here
that may be of help.

http://www.geocities.com/jeff_louie/...estructors.htm

Jeff

"Peter Oliphant" wrote:
I would assume in the following that 'instance' being set to 'nullptr'
should cause the instance of myClass that was created to no longer have any
pointers pointing to it, and therefore be 'destroyed':

ref myClass
{
public:
myClass() {}
~myClass() {} // never called
!myClass() {} // never called
} ;

main()
{
myClass^ instance = gcnew myClass() ;
instance = nullptr ; // shouldn't this cause destruction?
}

However, as indicated, neither the destructor or finalizer get called when
'instance' is set to 'nullptr'. Is the object previously pointed to by
'instance' still around (.e., it still has memory resources)? Isn't having
all existing pointers to an object either being set to nullptr or going out
of scope cause the object to be destructed? If not, what am I missing here?
If so, why is neither the destructor or finalizer called?

For context, using VS C++.NET 2005 Express in /clr mode, I'm trying to count
(using a static class variable) the number of existing instances of myClass.
It is easy to count the creations (bump counter in each constructor), but
how do I count the destructions?

thanks in advance for responses! : )

[==P==]

Nov 17 '05 #2
Hi Jeff,

Thanks for the response! : )

Ok, got a few questions then. How do I "force garbage collection"? Don't
know exactly what 'stack semantics' are (in contrast to the code sample I
provided), could you provide an equivalent to my code that IS in stack
semantic form?

Are you saying that the resources for the object previously pointed to by
'instance' are still 'valid' (even though there is no way to get to it from
the code since no pointers to it exist anymore) until the 'garbage
collector' decides to start garbage collecting, at which point the resources
may be released if needed?

The big question is as follows: Is there any call to a class that indicates
that it has just become elligible for garbage collection (that is, no
pointers exist that point to it)? That is, something that would trigger in
the sample code I gave when the only (or last) pointer to the object is set
to nullptr?

[==P==]

"JAL" <JA*@discussions.microsoft.com> wrote in message
news:E5**********************************@microsof t.com...
Peter... When a managed class is no longer reachable from root it is
eligible
for garbage collection. You can force the garbage collector just as a test
case to force the call to Finalize. In your example you are not using
stack
based semantics so the destructor will not be called. I wrote an artice
here
that may be of help.

http://www.geocities.com/jeff_louie/...estructors.htm

Jeff

"Peter Oliphant" wrote:
I would assume in the following that 'instance' being set to 'nullptr'
should cause the instance of myClass that was created to no longer have
any
pointers pointing to it, and therefore be 'destroyed':

ref myClass
{
public:
myClass() {}
~myClass() {} // never called
!myClass() {} // never called
} ;

main()
{
myClass^ instance = gcnew myClass() ;
instance = nullptr ; // shouldn't this cause destruction?
}

However, as indicated, neither the destructor or finalizer get called
when
'instance' is set to 'nullptr'. Is the object previously pointed to by
'instance' still around (.e., it still has memory resources)? Isn't
having
all existing pointers to an object either being set to nullptr or going
out
of scope cause the object to be destructed? If not, what am I missing
here?
If so, why is neither the destructor or finalizer called?

For context, using VS C++.NET 2005 Express in /clr mode, I'm trying to
count
(using a static class variable) the number of existing instances of
myClass.
It is easy to count the creations (bump counter in each constructor), but
how do I count the destructions?

thanks in advance for responses! : )

[==P==]

Nov 17 '05 #3
JAL
Peter.... I have use GC.Collect to force garbage collection for testing only.
I have also thrown an exception in finalize to document that finalize is
being called as main is exited. As for stack based semantics it would look
like this:

RAII r; // thats it

When an object is unreachable it is not valid in the sense that its methods
can be invoked. There is no reference counting by the garbage collector, it
normally simply searches the tree from root when memory runs low and if an
object is not reachable from root the object it can be collected.

"Peter Oliphant" wrote:
Hi Jeff,

Thanks for the response! : )

Ok, got a few questions then. How do I "force garbage collection"? Don't
know exactly what 'stack semantics' are (in contrast to the code sample I
provided), could you provide an equivalent to my code that IS in stack
semantic form?

Are you saying that the resources for the object previously pointed to by
'instance' are still 'valid' (even though there is no way to get to it from
the code since no pointers to it exist anymore) until the 'garbage
collector' decides to start garbage collecting, at which point the resources
may be released if needed?

The big question is as follows: Is there any call to a class that indicates
that it has just become elligible for garbage collection (that is, no
pointers exist that point to it)? That is, something that would trigger in
the sample code I gave when the only (or last) pointer to the object is set
to nullptr?

[==P==]

Nov 17 '05 #4
Aha, by george I think I've got it! :)

My main problem is that I got so use to 'old syntax' managed objects
requiring them to be instantiated by 'new'ing them into pointers. Didn't
realize the new /clr syntax allows for construction of non-pointer instances
('stack semantics'). Maybe the old syntax did to, but I kept getting a
compiler error if I tried to construct any other way (so I got use to doing
it this way always, except with things like 'int' and 'bool').That is, I
didn't realize that:

RAII r ;

was legal, I thought the only way to construct a managed object was like
this:

RAII^ r = gcnew RAII() ;

[ or, old syntax, RAII* r = new RAII() ; ]

One more question if you would be so kind. In order for the stack symantics
to be possible, doesn't it require the class have a default (i.e., no
parameter) constructor? Or, alternately, one would have to construct using a
valid constructor, ala (imagine the definition of call RAII is extended to
include a constructor of the form "RAII( int x)"):

RAII r(3) ;

Put simply, stack symantics still doesn't allow the creation of an object
instance without going though a valid public constructor, Yes?

[==P==]

"JAL" <JA*@discussions.microsoft.com> wrote in message
news:3F**********************************@microsof t.com...
Peter.... I have use GC.Collect to force garbage collection for testing
only.
I have also thrown an exception in finalize to document that finalize is
being called as main is exited. As for stack based semantics it would look
like this:

RAII r; // thats it

When an object is unreachable it is not valid in the sense that its
methods
can be invoked. There is no reference counting by the garbage collector,
it
normally simply searches the tree from root when memory runs low and if an
object is not reachable from root the object it can be collected.

"Peter Oliphant" wrote:
Hi Jeff,

Thanks for the response! : )

Ok, got a few questions then. How do I "force garbage collection"? Don't
know exactly what 'stack semantics' are (in contrast to the code sample I
provided), could you provide an equivalent to my code that IS in stack
semantic form?

Are you saying that the resources for the object previously pointed to by
'instance' are still 'valid' (even though there is no way to get to it
from
the code since no pointers to it exist anymore) until the 'garbage
collector' decides to start garbage collecting, at which point the
resources
may be released if needed?

The big question is as follows: Is there any call to a class that
indicates
that it has just become elligible for garbage collection (that is, no
pointers exist that point to it)? That is, something that would trigger
in
the sample code I gave when the only (or last) pointer to the object is
set
to nullptr?

[==P==]

Nov 17 '05 #5
JAL
Peter... Glad to hear that. As I recollect, if you don't write any
constructor the compiler will write a no arg constructor for you and only no
arg instantiation will be allowed. If you write any constructor, then only
your explicit constructors are available. There is no default copy
constructor or assignment operator for use on stack based ref classes. If you
try to return a stack based object from a method, the compiler will complain.

"Peter Oliphant" wrote:
Aha, by george I think I've got it! :)
...
RAII r(3) ;

Put simply, stack symantics still doesn't allow the creation of an object
instance without going though a valid public constructor, Yes?

[==P==]

Nov 17 '05 #6
ref MyRefClass
{
public:
MyRefClass() {}
~MyRefClass() {}
} ;

main()
{
MyRefClass instance;
// destructor ~MyRefClass() is called here
}
Nov 17 '05 #7
"bonk" wrote:
ref MyRefClass
{
public:
MyRefClass() {}
~MyRefClass() {}
} ;

main()
{
MyRefClass instance;
// destructor ~MyRefClass() is called here
}
So, what the OP's example does? a memory leak?
main()
{
myClass^ instance = gcnew myClass() ;
instance = nullptr ; // shouldn't this cause destruction?
}


Regards,
--PA
Nov 17 '05 #8
I believe it doesn't create a memory leak, but instead frees up memory the
garbage collector may use when it decides to, but won't call the finalizer
or destructor UNTIL it decides to.

So it isn't a 'leak' in the sense that it's memory the system has 'lost' or
has allocated and won't free up, but is instead memory which the system is
still in control of and can be freed up when desired, and will be freed up
upon application closing. Leaks typical remain after the application has
been closed because the system thinks the memory is still being used and/or
has lost the ability to de-allocate it since no pointer to it exists.

In theory, no ref class can possibly leak, that's the whole purpose behind
garbage collection...

[==P==]

PS - I'm the OP, and my initials are PO....lol

"Pavel A." <pa*****@NOwritemeNO.com> wrote in message
news:3B**********************************@microsof t.com...
"bonk" wrote:
ref MyRefClass
{
public:
MyRefClass() {}
~MyRefClass() {}
} ;

main()
{
MyRefClass instance;
// destructor ~MyRefClass() is called here
}


So, what the OP's example does? a memory leak?
main()
{
myClass^ instance = gcnew myClass() ;
instance = nullptr ; // shouldn't this cause destruction?
}


Regards,
--PA

Nov 17 '05 #9
JAL
Pavel... As written the storage on the heap will be released when the garbage
collector runs. However, this is not deterministic behaviour. You can still
have deterministic behaviour without stack based sematics if you are willing
to write code like:

RAII^ heaped= nullptr;
try
{
heaped= gcnew RAII();
heaped->SayHello();
Console::WriteLine(heaped->I);
}
finally
{
if (heaped != nullptr)
{
delete heaped;
heaped= nullptr;
}
}

But the stack based example is much simpler:

RAII r;
r.SayHello();
Console::WriteLine(r.I);

The destructor will be called even if an exception is thrown. So... this
smacks of a smart pointer, an exception safe object on the stack that
automagically releases resources newed on the heap.

"Pavel A." wrote:
"bonk" wrote:
ref MyRefClass
{
public:
MyRefClass() {}
~MyRefClass() {}
} ;

main()
{
MyRefClass instance;
// destructor ~MyRefClass() is called here
}


So, what the OP's example does? a memory leak?
main()
{
myClass^ instance = gcnew myClass() ;
instance = nullptr ; // shouldn't this cause destruction?
}


Regards,
--PA

Nov 17 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Lars Grøtteland | last post by:
Hello! I was able to compile my aplication in Managed /clr code. How can I refere one form (Windows Form(.NET)) in my app. It's ok to add it, but how can I go into that form? I was thinking of...
26
by: Michi Henning | last post by:
I've been having problem with destructors in the context of having ported C# code developed under .NET to Mono. What happens is that, on a dual-CPU machine, various parts of the code crash randomly...
8
by: Edward Diener | last post by:
I have a __value class which uses some legacy C++ code. So I wrapped the legacy C++ code in another __nogc class and have a pointer to that class as a member of my __value class. When the __value...
17
by: Peter Oliphant | last post by:
In the 'old days', we could create a pointer to an instance of a variable like so: int i = 58 ; int* i_ptr = &i ; int j = *i_ptr ; // j = 58 Now, in /clr how do we do the same? That is,...
6
by: nicolas.hilaire | last post by:
Hi all, i'm not totally clear with some concepts about managed and unmanaged code. I'm asking myself some questions : - i've a MFC app, i want to use the framework dotnet by switching to...
12
by: Greg | last post by:
For all new desktop apps is managed/CLR recommended? I.e. Native MFC/Win32 not recommended in general for new desktop apps? Speaking in general, not referring to exceptions (e.g. drivers) -- Greg...
1
by: Bern McCarty | last post by:
We upgraded a bunch of MEC++ code to C++/CLI about 10 months ago and we've noticed that our images bloated quite a lot in the process. Upon investigating I observed that when a /clr compiland...
5
by: Bern McCarty | last post by:
We upgraded a bunch of MEC++ code to C++/CLI about 11 months ago and we've noticed that our images bloated quite a lot in the process. Upon investigating I observed that when a /clr compiland...
3
by: David K in San Jose | last post by:
I'm using managed (CLR) C++ in VS2005 to create a Windows app that contains a form named "MyForm". In the code for that form I'm trying to invoke some static functions by using an array of function...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.