473,899 Members | 3,752 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Confused about gcnew and object lifetime

I wanted to take advantage of the large set of functionality offered by
the framework, so for my latest project I'm using managed C++ with .NET
v2. I'm using the gcnew operator in two different ways, and I'm
confused about the lifetime of objects and whether or not I should be
calling delete. Here are two examples:

ref class SYMBOL : public IComparable
{
public:
// Constructor / destructor
SYMBOL()
{
name = nullptr;
};
~SYMBOL()
{
if (name != nullptr)
{
delete name;
}
}

//Data
String^ name;
UInt32 relativeAddress ;

// Methods
virtual Int32 CompareTo(Objec t^ obj)
{
MODULE^ mod = dynamic_cast<MO DULE^>(obj);

return relative.Compar eTo(mod->relativeAddres s);
}
};

In the example above, the class is used to create a List
(System.Collect ions.Generic.Li st) of SYMBOL objects. For each addition
to the list (symbols), I do a gcnew of a SYMBOL object, add pass the
gcnew'ed handle to the List.Add method. I also do a gcnew of a String
object, and assign the gcnew'ed handle to the name member of the SYMBOL
object. As you can see, I am explicitly deleting the String object in
the SYMBOL destructor. Is this correct?

The other case is this:

void PARSER::ReadLog File(void)
{
FileInfo^ logFileI = gcnew FileInfo(logFil ename);
FileStream^ logFileS = logFileI->OpenRead();
logData = gcnew array<Byte>((in t)logFileI->Length);
int bytesRead = logFileS->Read(logData , 0, (int)logFileI->Length);

delete logFileI;
// TODO: Add some error checking, mechanism for returning 0-length
array on error
}

As you can see, I'm manually deleting the gcnew'ed FileInfo. Is this
correct?

Sorry if this is a basic question, but the info I've found on the net
is not consistent. In one place I found an "expert" saying that
"objects created with gcnew should never be deleted." However, that
doesn't make sense to me. I understand that after the app exits,
objects on the managed heap will eventually be gc'ed, but to be
completely right about memory management, shouldn't I be deleting
objects that I create?

Thanks,
-Chris

Mar 20 '06 #1
15 8342
I wanted to take advantage of the large set of functionality offered by
the framework, so for my latest project I'm using managed C++ with .NET
v2. I'm using the gcnew operator in two different ways, and I'm
confused about the lifetime of objects and whether or not I should be
calling delete. Here are two examples:


Yes,

The way I understood it you have to manually delete the object.
C++/CLI != C#

There was a very lively discussion a month ago about this topic in this very
newsgroup (Destructor: not gauranteed to be called?):
http://groups.google.nl/group/micros...c2007f860c0a46

It had a lot of input from lots of experienced people.
The thread makes a good read if you want to know more about this topic.

--

Kind regards,
Bruno.
br************* *********@hotma il.com
Remove only "_nos_pam"
Mar 21 '06 #2
Bruno van Dooren wrote:
I wanted to take advantage of the large set of functionality offered by
the framework, so for my latest project I'm using managed C++ with .NET
v2. I'm using the gcnew operator in two different ways, and I'm
confused about the lifetime of objects and whether or not I should be
calling delete. Here are two examples:

Yes,

The way I understood it you have to manually delete the object.
C++/CLI != C#


C# and C++/CLI have equivalent GC AFAIK. The problems with C++/CLI GC
are the exact same ones as those of C# (and Java for that matter).
There was a very lively discussion a month ago about this topic in this very
newsgroup (Destructor: not gauranteed to be called?):
http://groups.google.nl/group/micros...c2007f860c0a46

It had a lot of input from lots of experienced people.
The thread makes a good read if you want to know more about this topic.


I think you missed the point (not that I read the whole thread) - you do
not have to call delete if you don't care whether your destructor runs
or not in a timely manner (or even ever). This is true for Java (my area
of GC familiarity), C# and C++/CLI. It is only if the object in question
has a finalizer/destructor that frees up a non-memory resource, such as
a DB connection, socket or file, that you should manually "delete" it in
order to guarantee timely clean up.

Basically, the GC is adept at recycling memory when it gets low, but it
obviously doesn't know which objects to finalise in order to recycle
other resources, such as db connections. For example, you could end up
running out of available connections even though you only have 1
"reachable" db connection object, since the GC hasn't bothered to
finalize your old connections (presumably because it isn't low on memory).

Essentially, GC frees you from manual memory management but not from
manual resource management.

Tom
Mar 21 '06 #3
> I think you missed the point (not that I read the whole thread) - you do
not have to call delete if you don't care whether your destructor runs
or not in a timely manner (or even ever). This is true for Java (my area
of GC familiarity), C# and C++/CLI. It is only if the object in question
has a finalizer/destructor that frees up a non-memory resource, such as
a DB connection, socket or file, that you should manually "delete" it in
order to guarantee timely clean up.


Hi Tom,

I did not miss that point. In the thread I linked to someone already
mentioned that the
GC will eventually (whenever it is in the mood - if ever - as you say)
perform the garbage collection.
However, since lots of classes involve physical resources you have to manually
release them if you want to have some determinism in it to prevent resource
problems.

Since everything in my programming background revolves around some resources
or other,
The GC cannot solve any of my problems. I care as much about resources as
about memory.

Your remark reminded me that this is also true for C#. I just don't use C#
for anything
other than some test programs and private applications, which is why I
didn't think of it.

I agree that I should have been more specific.
Saying 'You have to do it manually If you want to be sure that it is released'
would have been much more precise.

--

Kind regards,
Bruno.
br************* *********@hotma il.com
Remove only "_nos_pam"
Mar 21 '06 #4
So maybe I didn't make it clear why I wanted the questions answered.
I'm not worried about running out of resources, and therefore wanting
to make sure that I'm explicility releasing them, I'm wanting to make
sure that resources aren't going to be GC'ed before I'm done with them.
I guess a better general question would be - does the GC ever
automatically release (delete) an object while the process owning the
object is still active?

Thanks,
-Chris

Mar 21 '06 #5
Here's some info I found on MSDN that provides some insight into this:

Code authored in Visual C++ and compiled with /clr will run a type's
destructor for the following reasons:

* If an object created using stack semantics goes out of scope. For
more information, see C++ Stack Semantics for Reference Types.
* If an exception is thrown during the object's construction.
* If the object is a member in an object whose destructor is
running.
* If you call the delete Operator (C++) on a handle (^ (Handle to
Object on Managed Heap)).
* If you explicitly call the destructor.

Mar 21 '06 #6
> So maybe I didn't make it clear why I wanted the questions answered.
I'm not worried about running out of resources, and therefore wanting
to make sure that I'm explicility releasing them, I'm wanting to make
sure that resources aren't going to be GC'ed before I'm done with them.
I guess a better general question would be - does the GC ever
automatically release (delete) an object while the process owning the
object is still active?


That should never happen.

Garbage collection only happens if all gc handles to an object on the
managed heap are out of scope. From that time on the GC is free to Dispose of
them at its own leisure.

Until that time your objects are safe.

--

Kind regards,
Bruno.
br************* *********@hotma il.com
Remove only "_nos_pam"
Mar 21 '06 #7
ce********@qual netics.com wrote:
I wanted to take advantage of the large set of functionality offered
by the framework, so for my latest project I'm using managed C++ with
.NET v2. I'm using the gcnew operator in two different ways, and I'm
confused about the lifetime of objects and whether or not I should be
calling delete. Here are two examples:
There's no need to invoke delete in either of the cases that you cited.
However, you touched on a case where you should call delete or use a
stack-allocated object:
void PARSER::ReadLog File(void)
{
FileInfo^ logFileI = gcnew FileInfo(logFil ename);
FileStream^ logFileS = logFileI->OpenRead();
logData = gcnew array<Byte>((in t)logFileI->Length);
int bytesRead = logFileS->Read(logData , 0, (int)logFileI->Length);

delete logFileI;
// TODO: Add some error checking, mechanism for returning 0-length
array on error
}


Here, you should be calling delete on logFileS, or at least executing
logFileS->Close() to make sure that the Win32 file handle is closed
deterministicly . Otherwise, that file will remain open (and locked) until
the FileStream object is collected. Unfortunately, the System.IO classes
don't implement copy constructors, so it's not possible to create them as
stack-based objects, so you're left with something like this:

void ReadLogFile(voi d)
{
FileInfo^ logFileI = gcnew FileInfo(logFil ename);
FileStream^ logFileS = logFileI->OpenRead();
try
{
logData = gcnew array<Byte>((in t)logFileI->Length);
int bytesRead = logFileS->Read(logData , 0, (int)logFileI->Length);
}
finally
{
delete logFileS;
}
}
-cd
Mar 21 '06 #8
I'm confused by your example:

* You do not delete the FileInfo object gcnew'ed
* You do delete the FileStream object returned from the FileInfo object

If any .NET API returns an object handle, if you want deterministic
resource cleanup should the caller of the API eventually call delete on
the object's handle?

For example, if I do { String^ newText = oldText->Remove(0, someChars)
}, is the API actually doing a gcnew of a String object, and therefore
is it now my responsibility to delete that object (or leave it up to
the GC to delete the object at some point).

Thanks,
-Chris

Mar 21 '06 #9
> * You do not delete the FileInfo object gcnew'ed
FileInfo only contains data. It does not hold resources. Therefore it does
not really matter how long it takes before it is GC'ed. At least from a
resource point of view.
* You do delete the FileStream object returned from the FileInfo object The filestream holds a resource (the file handle) so if it is not deleted
explicitly, it will be left open until the GC decides to delete it.
If any .NET API returns an object handle, if you want deterministic
resource cleanup should the caller of the API eventually call delete on
the object's handle? Yes.
For example, if I do { String^ newText = oldText->Remove(0, someChars)
}, is the API actually doing a gcnew of a String object, and therefore
is it now my responsibility to delete that object (or leave it up to
the GC to delete the object at some point).

Indeed.

--

Kind regards,
Bruno.
br************* *********@hotma il.com
Remove only "_nos_pam"
Mar 21 '06 #10

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

Similar topics

5
5491
by: Haoyu Zhang | last post by:
Dear Friends, Python assignment is a reference assignment. However, I really can't explain the difference in the following example. When the object is a list, the assignment seems to be a reference. However, when the object is a number, the story is so different. I don't understantd for what reason Python deals with them differently. The example is as follows: >>> a = >>> b = a
14
3175
by: MuZZy | last post by:
Hi, Lately i've been (and still am) fixing some memory leaks problems in the project i just took over when i got this new job. Among the other issues i've noticed that for localy created objects it makes difference to explicitly put them to null after working with them is done - it somehow makes the GC collect them sooner, like here: void SomeFunc() { MyClass c = new MyClass();
5
1647
by: Bit byte | last post by:
I have the following methods: static void Foo::setBar(const Bar*) ; //store a copy of Bar static const Bar* Foo::getBar(void) const ; //return an UNMODIFIABLE ptr to our internal copy In another part of my code , I retrieved and used Bar as follows: .... const Bar* temp = NULL ;
3
3173
by: hedbonker | last post by:
OK - I am new to .net C++. Trying to write a simple app that creates an XML output file based on some values that a user puts in a form. After looking in the help, the sample code provided was this: XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; settings.IndentChars = (" "); using (XmlWriter writer = XmlWriter.Create("personal.xml", settings)) { // Write XML data.
0
1211
by: pkolinko | last post by:
Hi everyone, I am writing a small low level embedded USB application using C++/CLI windows Forms. I am sort of new to the C++/CLI and having trouble understanding what happens in this very simple line of code: I have a reference class pic_usbapi, declared in "pic_usbapi.h". I want to create an object of the class and have a tracking handle for it.
0
1198
by: whm | last post by:
The page http://msdn2.microsoft.com/en-us/708fb7c4(VS.80).aspx has this code: ServiceController^ sc = gcnew ServiceController; if ( sc ) { ... Section 15.4.6 in ECMA 372 (the C++/CLI spec) seems to indicate that gcnew either returns a handle to an object or it throws but the Microsoft-written code above seems to imply that gcnew could return
3
2349
by: nagashre | last post by:
class A { public: A():a(0), b(0){} handleMyMsg( char* aa, char*bb); private: processMessage();
1
458
by: dogbert1793 | last post by:
Hello, Does one need to delete pointers allocated with gcnew? Or does the garbage collector do it? I always though the garbage collector did it, but I saw this example today on MSDN: StreamReader^ sr = gcnew StreamReader( "TestFile.txt" ); try
6
2707
by: better_cs_now | last post by:
Hello all, class Foo {/* Details don't matter */}; class Bar { public: Bar(): m_Foo(/* Construct a Foo however it wants to be constructed */); const Foo &GetFoo() const { return m_Foo; } private:
0
9843
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
11272
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
10863
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...
1
10971
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10494
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9666
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
8039
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
5887
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...
1
4720
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

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.