473,385 Members | 1,872 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,385 software developers and data experts.

Variable scope not what is expected?

Hi all,

I have some code similar to the following:

C#
MyClass mVer = ne w MyClass();

…in a member function
mVar.SendEvent( new Event() );

Managed C++

Ref class MyClass
{
Void SendEvent( Event^ event )
{
// event is collected by the GC during this call... why?
mUnmanagedPtr->SendUnmanagedEvent( event->GetUnmanagedEvent() );
}
}

For some reason the GC thinks its ok to collect the managed event object
before SendUnmanagedEvent returns. Standard scope rules dictate that event is
referenced until the C# mVar.SendEvent function returns. At least that’s my
understanding. Because of this strange behavior I get random crashes when the
GC occasionally collects my events during the call.

Is this a bug? Is my expectation wrong? Am I doing something wrong?

Oct 2 '07 #1
3 1423
Scythen wrote:
[...]
Ref class MyClass
{
Void SendEvent( Event^ event )
{
// event is collected by the GC during this call... why?
mUnmanagedPtr->SendUnmanagedEvent( event->GetUnmanagedEvent() );
}
}

For some reason the GC thinks its ok to collect the managed event object
before SendUnmanagedEvent returns. Standard scope rules dictate that event is
referenced until the C# mVar.SendEvent function returns. At least that’s my
understanding. Because of this strange behavior I get random crashes when the
GC occasionally collects my events during the call.

Is this a bug? Is my expectation wrong? Am I doing something wrong?
It's not a bug. Your expectation is wrong. But, your misunderstanding
is not all that unusual or even unsurprising.

The GC will collect any reference that is no longer in use. The problem
comes in determining "use". As you've found, "use" is not defined
according to scope. It is literally defined according to "use".

So, in the code you posted, the object instance is not referred to by
any code after it's used to obtain the unmanaged event data (via
GetUnmanagedEvent()). The GC knows this and believes that since you are
not using that object any more, there is no need to keep it around.

To fix the issue, you need to explicitly tell the GC that the lifetime
of the object needs to be extended. You can do this by adding a
statement reading "GC.KeepAlive(event);" after your call to
SendUnmanagedEvent(). This ensures that the reference is not considered
unused until after that statement, and so won't be collected during the
call (or any other statements prior to that statement).

Pete
Oct 2 '07 #2
Scythen <Sc*****@discussions.microsoft.comwrote:
I have some code similar to the following:

C#
MyClass mVer = ne w MyClass();

?in a member function
mVar.SendEvent( new Event() );

Managed C++

Ref class MyClass
{
Void SendEvent( Event^ event )
{
// event is collected by the GC during this call... why?
mUnmanagedPtr->SendUnmanagedEvent( event->GetUnmanagedEvent() );
}
}

For some reason the GC thinks its ok to collect the managed event object
before SendUnmanagedEvent returns. Standard scope rules dictate that event is
referenced until the C# mVar.SendEvent function returns. At least that?s my
understanding. Because of this strange behavior I get random crashes when the
GC occasionally collects my events during the call.

Is this a bug? Is my expectation wrong? Am I doing something wrong?
Your expectation is incorrect.

The garbage collector is free to collect the object as soon as the JIT
can tell that the reference itself is no longer used.

Now, in your code that means that unless event->GetUnmanagedEvent()
returns something which in turn references event itself, there's
nothing referencing the Event object any more and it can be garbage
collected.

From the Unified C# 3.0 spec:

<quote>
2. If the object, or any part of it, cannot be accessed by any
possible continuation of execution, other than the running of
destructors, the object is considered no longer in use, and it becomes
eligible for destruction. The C# compiler and the garbage collector may
choose to analyze code to determine which references to an object may
be used in the future. For instance, if a local variable that is in
scope is the only existing reference to an object, but that local
variable is never referred to in any possible continuation of execution
from the current execution point in the procedure, the garbage
collector may (but is not required to) treat the object as no longer in
use.
</quote>

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Oct 2 '07 #3

"Scythen" <Sc*****@discussions.microsoft.comha scritto nel messaggio
news:CE**********************************@microsof t.com...
Hi all,

I have some code similar to the following:

C#
MyClass mVer = ne w MyClass();

…in a member function
mVar.SendEvent( new Event() );

Managed C++

Ref class MyClass
{
Void SendEvent( Event^ event )
{
// event is collected by the GC during this call... why?
mUnmanagedPtr->SendUnmanagedEvent(
event->GetUnmanagedEvent() );
}
}

For some reason the GC thinks its ok to collect the managed event object
before SendUnmanagedEvent returns. Standard scope rules dictate that event
is
referenced until the C# mVar.SendEvent function returns. At least that’s
my
understanding. Because of this strange behavior I get random crashes when
the
GC occasionally collects my events during the call.

Is this a bug? Is my expectation wrong? Am I doing something wrong?
GC is thinking in this way:

SendEvent
0. ref event
1. new tempvar=ref event->GetUnmanagedEvent()
2. ref event=null (we have now the tempvar so event is no longer needed,
"used")
3. ref function=SendUnmanagedEvent -Call (tempvar is rooted to
SendEvent)
5. tempres=null
6. function=null

Void SendEvent( Event^ event )
{
// event is collected by the GC during this call... why?
mUnmanagedPtr->SendUnmanagedEvent(
event->GetUnmanagedEvent() );
}
Oct 3 '07 #4

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

Similar topics

0
by: Rajarshi Guha | last post by:
Hi, I have been translating some Algol code to python and am facing a problem. Heres an example of the code: def f(x): print 'hello' c =0 def g(y):
6
by: Brian Jones | last post by:
I'm sure the solution may be obvious, but this problem is driving me mad. The following is my code: class a(object): mastervar = def __init__(self): print 'called a'
166
by: Graham | last post by:
This has to do with class variables and instances variables. Given the following: <code> class _class: var = 0 #rest of the class
10
by: Not Available | last post by:
On the host server: namespace JCart.Common public class JCartConfiguration : IConfigurationSectionHandler private static String dbConnectionString; public static String ConnectionString { get...
6
by: Maarten | last post by:
Here is a nice problem. I have two scripts, one calling the other with via an include. The script that is included contains a variable, a function and a call to that function. The variable needs to...
8
by: Florian Daniel Otel | last post by:
Hello all, As the subject says, I am a newcomer to Python and I have a newcomer question wrt namespaces and variable scope. Obviously, I might be missing smth obvious, so TIA for the patience...
18
by: Andrew | last post by:
Hi, I have a scenario in which both the source and format string for a sscanf() call is selected *at runtime*. The number of format conversions/substitutions is known as well as the maximum...
9
by: NevilleDNZ | last post by:
Can anyone explain why "begin B: 123" prints, but 456 doesn't? $ /usr/bin/python2.3 x1x2.py begin A: Pre B: 123 456 begin B: 123 Traceback (most recent call last): File "x1x2.py", line 13,...
1
pbmods
by: pbmods | last post by:
VARIABLE SCOPE IN JAVASCRIPT LEVEL: BEGINNER/INTERMEDIATE (INTERMEDIATE STUFF IN ) PREREQS: VARIABLES First off, what the heck is 'scope' (the kind that doesn't help kill the germs that cause...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
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
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...

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.