473,402 Members | 2,061 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,402 software developers and data experts.

Arrays and gcroot

I am storing an array of strings in an unmanaged MFC class using gcroot as
follows:
gcroot<array<System::String^>^m_pArr;

Nothing out of the ordinary there. However, if I try to use "delete m_pArr"
in the code in order to deterministically delete it, I get the following
error in VS05:
error C2440: 'delete' : cannot convert from 'gcroot<T>' to 'void *'

If I use the same with something other than an array i.e. using gcroot and
then doing a delete, its fine.

Any ideas on why the compiler is throwing this error?

Thanks.

Feb 15 '07 #1
6 6974
On 15 fév, 02:02, Al <A...@discussions.microsoft.comwrote:
I am storing an array of strings in an unmanaged MFC class using gcroot as
follows:
gcroot<array<System::String^>^m_pArr;

Nothing out of the ordinary there. However, if I try to use "delete m_pArr"
in the code in order to deterministically delete it, I get the following
error in VS05:
error C2440: 'delete' : cannot convert from 'gcroot<T>' to 'void *'
Well, gcroot is not a pointer type, so there is no way to call delete
on it. OTOH, gcroot will release the managed memory it holds when it
goes out of scope (when it's destructor is called), or when you assign
nullptr to it. Note that this will only release the GCHandle to the
managed object, so:
- if the managed object is still referenced somewhere else, it won't
be garbage-collected.
- even if there are no other references, the managed object won't be
deleted immediatly : it will just be marked as ready for garbage-
collection.
- the managed object's Dispose method won't be called immediatly (if
implemented).

If you need true ownership semantics on the managed object, you should
use auto_gcroot (with all the same subtle caveats as std::auto_ptr
concerning weird ownership semantic).
If I use the same with something other than an array i.e. using gcroot and
then doing a delete, its fine.
No it isn't. I believe that in the other case, you are declaring a
pointer to a gcroot (eg, " gcroot<MyStuff^>* " - note the final
pointer star).

Please show us some code and explain what it is you are trying to
achieve if you need more help.

Arnaud
MVP - VC

Feb 15 '07 #2

<ad******@club-internet.frwrote in message
news:11**********************@k78g2000cwa.googlegr oups.com...
On 15 fév, 02:02, Al <A...@discussions.microsoft.comwrote:
I am storing an array of strings in an unmanaged MFC class using gcroot as
follows:
gcroot<array<System::String^>^m_pArr;

Nothing out of the ordinary there. However, if I try to use "delete
m_pArr"
in the code in order to deterministically delete it, I get the following
error in VS05:
error C2440: 'delete' : cannot convert from 'gcroot<T>' to 'void *'
For any gcroot<T^instance
Try
delete (T^) instance;
to dispose instance deterministically. The cast explicitly invokes the user
defined conversion.
Better yet, to avoid the C-style cast,
delete instance->operator T^();
I wish there was a user_cast<>() operator for that. Probably can make one
easily enough with templates that works for any type, but I doubt that
modifiers would be handled properly.

Anyway, CLI arrays don't implement IDisposable, even when the member type
does, so in your particular case there's no need to call delete at all. But
this method has an advantage over calling Dispose directly in that it can be
used in a template that accepts any managed type whether or not it
implements IDisposable.
Feb 15 '07 #3
ad******@club-internet.fr wrote:
Well, gcroot is not a pointer type, so there is no way to call delete
on it.
My understanding is that calling delete on a gcroot actually calls
Dispose on the contained managed object. Obviously this only makes sense
if gcroot holds an IDisposable object. array<>^ and String^ are not
IDisposable and they don't need deterministic destruction, they're
simply garbage collected.

The way I understand it is that
- gcroot automatically releases the GCHandle that it manages (decreasing
its reference counter), but it doesn't Dispose.
- auto_gcroot not only releases the GCHandle, but it also calls Dispose
on the contained object.

Tom
Feb 15 '07 #4

"Tamas Demjen" <td*****@yahoo.comwrote in message
news:uX*************@TK2MSFTNGP05.phx.gbl...
ad******@club-internet.fr wrote:
>Well, gcroot is not a pointer type, so there is no way to call delete
on it.

My understanding is that calling delete on a gcroot actually calls Dispose
on the contained managed object. Obviously this only makes sense if gcroot
holds an IDisposable object. array<>^ and String^ are not IDisposable and
they don't need deterministic destruction, they're simply garbage
collected.
delete is an operator, and thus the compiler semantics for its use can't be
changed by gcroot, which is a template class and not a true keyword. delete
can only be used with pointers and tracking handles. So if you want to
dispose an object held by a gcroot, you'll have to get the tracking handle
out first.
Feb 15 '07 #5
Ben Voigt wrote:
delete is an operator, and thus the compiler semantics for its use can't be
changed by gcroot, which is a template class and not a true keyword. delete
can only be used with pointers and tracking handles. So if you want to
dispose an object held by a gcroot, you'll have to get the tracking handle
out first.
A conversion operator can introduce pointer or tracking handle semantics:

struct C
{
operator int* () const { return 0; }
};

void test()
// do not run this, but it is legal code that compiles
{
C c;
delete c; // operator int* is implicitly called here
}

This is contraversial, and most smart pointer implementations don't have
such a conversion operator. gcroot<T>, however, provides it: "operator T
() const". That's why you could normally call delete on a gcroot, and it
would work:

ref class Managed
{
public:
~Managed() { }
};
gcroot<Managed^m;
delete m; // this is OK, it calls Managed::Dispose,
/ /via the implicit conversion operator T() const

However, when Managed is an array or String, or anything that doesn't
support the Dispose pattern, it won't work. That's when you get the
"cannot convert from 'gcroot<T>' to 'void*'" error:

gcroot<array<String^>^m;
delete m; // this causes an error, array can't be deleted

auto_gcroot itself calls delete, but it uses an explicit conversion:
delete _element_type(m_ptr);

Tom
Feb 15 '07 #6

"Tamas Demjen" <td*****@yahoo.comwrote in message
news:%2****************@TK2MSFTNGP03.phx.gbl...
Ben Voigt wrote:
>delete is an operator, and thus the compiler semantics for its use can't
be changed by gcroot, which is a template class and not a true keyword.
delete can only be used with pointers and tracking handles. So if you
want to dispose an object held by a gcroot, you'll have to get the
tracking handle out first.

A conversion operator can introduce pointer or tracking handle semantics:

struct C
{
operator int* () const { return 0; }
};

void test()
// do not run this, but it is legal code that compiles
{
C c;
delete c; // operator int* is implicitly called here
}
Yes, you're right, delete can cause an implicit conversion (I didn't expect
that).

The explicit conversion is still much clearer.
Feb 15 '07 #7

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

Similar topics

0
by: igal.ioffe | last post by:
Hi All, I've run into a problem, converting a native project into mixed mode, where usage of gcroot point in mixed mode causes a fatal CLR engine exception. Here is a tiny code extract:...
2
by: Steve McLellan | last post by:
Hi, I see that GCHandle can encapsulate a weak reference, but gcroot appears to only allow 'normal' GCHandles. Is this correct or is there something I've missed? Ta, Steve
5
by: Gerhard Menzl | last post by:
Has anyone ever tried to sort a Standard Library container of gcroots? I have run into the problem that somewhere deep in the Library logic (in line 338 of <memory>, to be precise) the destructor...
2
by: Dave | last post by:
I have a few C# .NET components which might implement one or several interfaces, let say I1, I2 and I3. The unmanaged C++ client consumes this component using gcroot template pointer. How...
0
by: Rob Haynes | last post by:
I have a DLL with vanilla C functions implemented. I'd like these functions to become wrappers for a managed object. So, I was thinking that the first call would save a pointer statically to the...
2
by: Maxwell | last post by:
Hello, Im using MC++ VS.NET 2003 and am quite confused with with gcroot template and its use. The issue I am confused about is the need to (or not) delete a pointer to a managed object that you...
4
by: John | last post by:
I'm having a major problem trying to use value types like System::Drawing::Rectangle with std::vector. Is it possible to use STL containers with these type of objects, or am I just doing something...
6
by: =?Utf-8?B?RmFiaWFu?= | last post by:
Hello, I have a class hierarchy distributed over 3 native C++ dlls. The base class has a .NET Windows.Form for status output via a gcroot<>. The gcroot is declared private - the sub classes only...
6
by: Bob Altman | last post by:
Hi all, In C++/CLI (VS 2005) I have a C++ module compiled with /clr that contains a module-level gcroot variable: static gcroot<MyList^m_myList = gcnew MyList; In the above statement,...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
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
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.