473,769 Members | 3,844 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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 1331
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*@discussion s.microsoft.com > wrote in message
news:E5******** *************** ***********@mic rosoft.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*@discussion s.microsoft.com > wrote in message
news:3F******** *************** ***********@mic rosoft.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*****@NOwrit emeNO.com> wrote in message
news:3B******** *************** ***********@mic rosoft.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::WriteL ine(heaped->I);
}
finally
{
if (heaped != nullptr)
{
delete heaped;
heaped= nullptr;
}
}

But the stack based example is much simpler:

RAII r;
r.SayHello();
Console::WriteL ine(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
795
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 having a button click on one form, and go into the .NET form on that click. But I can't figure out how to do this. I can't refer it to the namespace, can I? I included the Form01Net.h file in my app.
26
2723
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 (and rarely). This always happens during process shutdown, after some thread has called System.Environment.Exit(). Clearly, some sort of race condition. Note that what follows only applies to destructors that are called when the process shuts...
8
1807
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 class is created, I dynamically allocate an object of the class with the legacy C++ code. However because the __value class has no destructor, I can never release that allocated memory. Why does a __value class allow no destructor ? Without it I...
17
2412
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, if I replace '*' with '^' what do I replace '&' with to generate a 'pointer' (is 'x^' called a 'reference' per chance?) to the instance? That is:
6
1461
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 /clr compilation mode. Is my app in CLR, or only the call to the
12
1533
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 McPherran www.McPherran.com
1
1452
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 includes a header file for a native type that has an inlined copy constructor, that both the inlined copy constructor and the inlined destructor for that same type will end up in my mixed image, even though there is no reference made to that native...
5
1492
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 includes a header file for a native type that has an inlined copy constructor, that both the inlined copy constructor and the inlined destructor for that same type will end up in my mixed image, even though there is no reference made to that native...
3
4846
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 pointers (delegates). I assume I need to use the array< T keyword to allocate an array of delegates, and then initialize the array by setting each array element to the pointers (handles) of the functions I'll be invoking. I've been trying to...
0
9422
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10206
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10035
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8863
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7403
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5293
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5441
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3949
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2811
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.