{length=error: cannot obtain value}

D

Dominiek

Hi,

I have a strange problem.

during the developement of my program, while progressively writing more and
more code, the callstack of my program gets deeper and deeper (7 levels).
Then, all of a sudden, when calling a Sub with 2 parameters, a Hashtable(19
items) and a ArrayList(9 items), the value of these variables is gone, the
debugger reports the value as {length=error: cannot obtain value}.

Passing them ByRef does not seem to solve the problem. IMHO, this seems to
be a problem with the stacksize.

Could somebody please help me with this?


TIA
Dominiek
 
A

Armin Zingler

Dominiek said:
during the developement of my program, while progressively writing
more and more code, the callstack of my program gets deeper and
deeper (7 levels). Then, all of a sudden, when calling a Sub with 2
parameters, a Hashtable(19 items) and a ArrayList(9 items), the value
of these variables is gone, the debugger reports the value as
{length=error: cannot obtain value}.

Passing them ByRef does not seem to solve the problem. IMHO, this
seems to be a problem with the stacksize.

7 levels is for sure not a problem with the stack size - unless you've got
really many local variables. Apart from this, you should get a
StackOverflowException.

I also had this problem, but *only* when using certain functions in the
managed DirectX assemblies. It's been forwarded as a bug to the dev team. I
guess you are not using managed DirectX? If you don't use it, sorry, I don't
have an explanation. You could narrow the problem down to as few lines as
possible and post it to microsoft.public.vsnet.ide or
microsoft.public.vsnet.debugging
 
D

Dominiek

Hey Armin,

Thanx for your reply

No, I'm not working with managed DirectX
No, I also didn't receive a StackOverflowException

I'm working with a lot of Structure's, which I pass ByVal from the upper
layer of my program. I just now changed all the passes ByVal to ByRef, and
now it seems to be working (for the moment). However, I think this issue
will resurface when the program increases in size.

I will follow your suggestion and forward this to the proposed newsgroups


Thnax
Dominiek
 
F

Fergus Cooney

Hi Dominek,

Structures, when passed ByVal, are stored on the stack. When passed ByRef
they are 'boxed' on the heap and a reference passed on the stack instead. This
is why your program now works. Keep it ByRef and you will probably stay clear
of trouble.

Another option would be to reduce those structures by putting some chunks
of their contents into independant classes. This might be useful from a
conceptual point of view too.

Another option, perhaps the best, is simply to change Structure to Class
for some of the bigger Structures. This has a performance advantage when done
with Structures that are passed in and out of methods - whether you use ByVal
<or> ByRef..

As I mentioned, with ByRef, the Structure is 'boxed' and the reference
passed . Each time this happens, a block of memory must be allocated and the
Structure copied into it. With ByVal, the Structure is again copied, but this
time directly to the stack. Similarly, when a Structure is passed back from a
Function, another copy takes place. So Structuures are being copied around all
the time.

In contrast, Objects stay where they are and only the reference is
shuffled around.

Is there any particular reason/advantage in having these large objects as
Structures?

Regards,
Fergus
 
J

Jay B. Harlow [MVP - Outlook]

Dominiek,
In addition to Fergus's comments

Unless you specifically need structures, convert them to Classes!

Per the .NET Design Guidelines for Class Library Developers.

http://msdn.microsoft.com/library/d...genref/html/cpconvaluetypeusageguidelines.asp

Structures should:
- act like primitive types
- have an instance size under 16 bytes
- are immutable
- value semantics are desirable

Basically if your structure has more than 4 fields, you should seriously
consider using a class instead of a structure. As classes exist on the heap
and a reference to the class is passed as the ByVal parameter, where as
structures exist on the stack and a copy of the structure is passed as a
ByVal parameter.

You should reserve ByRef parameters for when you actually need to modify the
caller's variable, not as an optimization technique.

Hope this helps
Jay

Dominiek said:
Hey Armin,

Thanx for your reply

No, I'm not working with managed DirectX
No, I also didn't receive a StackOverflowException

I'm working with a lot of Structure's, which I pass ByVal from the upper
layer of my program. I just now changed all the passes ByVal to ByRef, and
now it seems to be working (for the moment). However, I think this issue
will resurface when the program increases in size.

I will follow your suggestion and forward this to the proposed newsgroups


Thnax
Dominiek

Armin Zingler said:
7 levels is for sure not a problem with the stack size - unless you've got
really many local variables. Apart from this, you should get a
StackOverflowException.

I also had this problem, but *only* when using certain functions in the
managed DirectX assemblies. It's been forwarded as a bug to the dev
team.
 
D

Dominiek

Thanx to All

Will start to convert my structs into Classes




Jay B. Harlow said:
Dominiek,
In addition to Fergus's comments

Unless you specifically need structures, convert them to Classes!

Per the .NET Design Guidelines for Class Library Developers.

http://msdn.microsoft.com/library/d...genref/html/cpconvaluetypeusageguidelines.asp

Structures should:
- act like primitive types
- have an instance size under 16 bytes
- are immutable
- value semantics are desirable

Basically if your structure has more than 4 fields, you should seriously
consider using a class instead of a structure. As classes exist on the heap
and a reference to the class is passed as the ByVal parameter, where as
structures exist on the stack and a copy of the structure is passed as a
ByVal parameter.

You should reserve ByRef parameters for when you actually need to modify the
caller's variable, not as an optimization technique.

Hope this helps
Jay
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top