473,671 Members | 2,384 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Please Explain where will the struct be stored if it is declared inside the Class

Hi all,
Would you please explain me where will be the heap stored if it
is declared inside the Class, As class is a reference type, so it gets
stored on the heap, but struct is a value type-stored on the stack

Regards

thomson

Nov 17 '05 #1
9 2665
No, a struct is not a value type stored on the stack.

A struct is a value type stored on the stack _if_ it is declared as a
local variable in a method.

A struct is a value type stored on the heap along with the rest of the
information for a class if the struct is declared as a member of the
class.

Remember: a struct is a value type just like an int or a double. If you
declare an int as a class member, where is it stored? A struct would be
stored in the same place. If you declare an int as a local variable in
a method, where is it stored? A struct would be stored in the same
place.

Nov 17 '05 #2
Hi bruce,
Frankly Iam in a bit of confusion with the answer you have
send, Can u explain me in detail
Regards

thomson

Bruce Wood wrote:
No, a struct is not a value type stored on the stack.

A struct is a value type stored on the stack _if_ it is declared as a
local variable in a method.

A struct is a value type stored on the heap along with the rest of the
information for a class if the struct is declared as a member of the
class.

Remember: a struct is a value type just like an int or a double. If you
declare an int as a class member, where is it stored? A struct would be
stored in the same place. If you declare an int as a local variable in
a method, where is it stored? A struct would be stored in the same
place.


Nov 17 '05 #3

"thomson" <sa**********@y ahoo.com> wrote in message
news:11******** *************@g 44g2000cwa.goog legroups.com...
Hi bruce,
Frankly Iam in a bit of confusion with the answer you have
send, Can u explain me in detail


It doesn't get much more detailed than Jon's article:

http://yoda.arachsys.com/csharp/memory.html
Nov 17 '05 #4

"Daniel O'Connell [C# MVP]" <onyxkirx@--NOSPAM--comcast.net> wrote in
message news:%2******** *******@tk2msft ngp13.phx.gbl.. .

"thomson" <sa**********@y ahoo.com> wrote in message
news:11******** *************@g 44g2000cwa.goog legroups.com...
Hi bruce,
Frankly Iam in a bit of confusion with the answer you have
send, Can u explain me in detail


It doesn't get much more detailed than Jon's article:

http://yoda.arachsys.com/csharp/memory.html


Agreed, just one small remark though, The article states "Every static
variable is stored on the heap", this is not completely correct if Jon here
meant the GC heap.
Static variables are not stored on the GC heap, but they live on a private,
per application domain heap, more precisely, on the "High Frequency heap"
within the loader heap. So, if you ever wonder where the PairOfInts static
counter variable lives, well it's on the "High Frequency Heap".

Willy.

Nov 17 '05 #5
OK... forget about structs for a second. Let's talk only about native
types (like ints, longs, doubles, and floats) and classes.

There are only two places that things are stored in a running .NET
program. (Actually, as Willy pointed out, there are three: static
things are stored elsewhere, but we'll ignore those for now.) Something
can be stored either on the stack, or on the heap.

First, think about the stack. What is it? It is a place to store the
local variables that you declare in methods, and arguments to method
parameters. So, if you have code like this:

public decimal PowerOf(decimal value, int power)
{
decimal result = 1;
for (int i = 0; i < power; i++)
{
result *= power;
}
return result;
}
....
decimal x = PowerOf(2, 8);

Yes, I realize that this is a cheesy example (and the method doesn't
even work for negative powers), but take a look at what's going on here
with respect to the stack.

In the main program, down below, x is allocated on the stack because
it's a local (non-static) variable. 2 and 8 are copied onto the stack,
because they're arguments to PowerOf. Within PowerOf, result and i are
also allocated space on the stack because they're local variables. The
return value from PowerOf is also copied onto space allocated on the
stack, and then copied from that space into the variable x, which as
you recall was allocated space on the stack.

So, in this example, everything is happening on the stack. The heap
isn't involved at all.

A struct would act exactly the same as any of these decimals and ints.
A struct variable declared as a local (non-static) variable would be
allocated space on the stack. A struct passed to a method as an
argument would be _copied_ onto the stack (just as 2 and 8 were copied
onto the stack).

Now let's look at what happens with classes and the heap:

public class MyClass
{
private int classInt = 0;
private decimal classDecimal = 15.0;

public SomeOtherClass DoSomeStuff(Yet AnotherClass
yetAnotherInsta nce)
{
SomeOtherClass someOtherInstan ce = new SomeOtherClass( );
...
return someOtherInstan ce;
}
}
....
MyClass mine = new MyClass();
SomeOtherClass other = mine.DoSomeStuf f(new YetAnotherClass ());

Again, a silly method and a silly call, but let's look at what's going
on.

The first thing that happens is that a new instance of MyClass is
created _on the heap_, and a _reference_ to that instance (the space
allocated for the class information on the heap) is saved in "mine",
which is allocated _on the stack_ because it's a local variable. So
what was saved on the heap? Well. every instance of MyClass contains
two class members, "classInt" and "classDecim al". So, space for an int
and a decimal was reserved on the heap, those variables were
intialized, and a reference to that heap location (a pointer, if you
will) was saved in the variable "mine", which is located on the stack.

Every time we create a new instance of MyClass, space for yet another
int and decimal will be created on the heap.

Notice, however, that everything on the heap eventually comes back to
the stack. What is stored on the stack in the case of class instances
are _references_ or _pointers_ to the heap location where the class
information is stored.

The next thing that happens is that we create an instance of
YetAnotherClass in order to pass it to mine.DoSomeStuf f. The instance
of YetAnotherClass is allocated space on the heap... space for whatever
class members it declares (we can't see the declaration, so we don't
know how much space it needs). Then, a reference to that instance of
YetAnotherClass is placed on the stack as an argument to DoSomeStuff.

DoSomeStuff creates a new instance of SomeOtherClass. Again, space for
whatever members SomeOtherClass defines is reserved on the heap, and
the members of SomeOtherClass are initialized into that heap space. A
reference (or pointer) to this instance is stored in someOtherInstan ce
on the stack (because someOtherInstan ce is a local variable).

When DoSomeStuff returns, it copies the reference (pointer) to the
instance of SomeOtherClass into space allocated on the stack for its
return value. Back in the main program, this reference is copied into
the variable "other", which has space reserved on the stack (because
it's a local variable to the main program). So, we're left with "other"
containing a reference (pointer) to an instance of SomeOtherClass,
which stores its members in space on the heap.

So, now, what about structs? Well, if we were to change classInt and
classDecimal to user-defined struct types, _nothing would change_. When
space was allocated for MyClass on the heap, .NET would allocate enough
space to hold all of the information for the two structs, just as
though they were ints or decimals. It would initialize the space for
those structs with some intial values, just as you would initialize an
int or a decimal, and then it would put a reference to the MyClass
instance's heap space (which contains the information for the two
structs) on the stack. Again, all that goes on the stack in this case
is a simple reference (pointer) to the information on the heap.

As I said: structs act exactly like ints, doubles, floats, or decimals.
When passed as arguments to methods they are copied onto the stack.
When returned from methods, they are returned on the stack. When you
have local variables of a "struct" type, space for the entire struct's
information is allocated on the stack. When you assign them from one
variable to another, they are copied.

When a struct forms part of the information (the "state") for a class
instance, space for that struct is allocated on the heap along with
(and in the same memory as) the ints, doubles, and decimals that make
up the rest of the class's state information.

If you can understand how basic types like ints and decimals are
treated by the compiler and the CLR, then you understand how structs
are treated: exactly the same.

Nov 17 '05 #6
What I think is weird is if you have a class field int and a class
field object and if you set object; now if you set the object to the
value of int it will box.

Example

public class NewTest
{
public NewTest(int x)
{
g = x;
//will box even tough they're both on the heap.
obj = g;
}

int g = 0;
object obj = null;
}

Nov 17 '05 #7
Willy Denoyette [MVP] <wi************ *@telenet.be> wrote:
It doesn't get much more detailed than Jon's article:

http://yoda.arachsys.com/csharp/memory.html


Agreed, just one small remark though, The article states "Every static
variable is stored on the heap", this is not completely correct if Jon here
meant the GC heap.
Static variables are not stored on the GC heap, but they live on a private,
per application domain heap, more precisely, on the "High Frequency heap"
within the loader heap. So, if you ever wonder where the PairOfInts static
counter variable lives, well it's on the "High Frequency Heap".


Righto - I'll amend the article when I get some time.

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 17 '05 #8
There are two reasons why you couldn't just grab a reference to the int
g and stuff that reference into "obj" and call it a day.

First, objects have more associated with them than just their data. In
my example above I didn't mention that allocating space for an object
on the heap also allocates other stuff that goes along with it. At the
very least, .NET allocates space for some sort of marker (probably a
pointer) that indicates what type of object the heap-allocated data
belongs to. Remember that at run time an object knows what type it is
(and never forgets that). Even if you do this:

ArrayList list = new ArrayList();
object obj = list;

the variable "obj" contains a reference that points into the heap to
object data that "knows" that it is an ArrayList. The only way it can
"know" that is to have some hidden data stored on the heap along with
the members you declared... hidden data that indicates what kind of
object it is. (There is also at least a vtable, and probably other
junk. Suffice to say that the member data isn't all there is.)

The int g, as part of NewTest, _is_ stored on the heap, but it doesn't
have all of that surrounding object information stored with it. It's
just 32 bits of integer data. When you assign it to "obj", you want to
"cut it loose" and have it live on its own outside the confines of its
declaring class instance. So, it needs to be boxed, which involves more
than just copying the 32 bits into some other heap location: it needs
additional information about what kind of object it is (an Int32).

Second, .NET has to work this way in order to maintain security and
code sanity. Think of what would happen if it didn't.

The whole point of having private members like g (well, you didn't
declare it private, but you should have) is to _encapsulate_ object
state so that the only way you can monkey with the value of a member
like g is to call a property or method of NewTest. So, you don't want
to be able to do things that break encapsulation. At least, you don't
want to be able to do things that unexpectedly break encapsulation.

Now, let's change .NET's semantics so that g doesn't get boxed. As I
noted above, there is another reason why that's impossible, but let's
ignore that for the moment. Now, in our theoretical CLR, when you say

object obj = g;

you just put a reference to g in "obj", and leave g where it was. Now,
let's say, you return "obj" from some property of NewTest... you hand
it off to the outside world.

Now you have a problem: you've toasted your encapsulation of "g". Now
anyone who has their mitts on a copy of that reference can modify "g"
and there's nothing you can do about it, there is no way to react to
it, and therefore no way to guarantee that your internal state is
self-consistent. As a NewTest object, your ability to control your
internal state and guarantee its vailidity has just been compromised.
Nasty.

This leads right back to C/C++ pointers, and all of the problems that
come with them.

Yes, if g were an ArrayList instead of an int, you could return a
reference to it and you run into a similar problem, but not the same
problem. Your caller can interact with the instance to which you
returned a reference and change _its_ state, but your caller still
can't change the reference you're holding and make it point to another
object.

Basically, copying on a box or unbox had the nice side-effect of
maintaining guarantees about who can do what to your class's members.
As I noted in the first part of this post, the CLR really doesn't have
any choice when it comes to copying on box / unbox. However, even if it
did have a choice, I would still want it to act the way it does now; a
change in behaviour would lead us back to annoying pointer problems.

Nov 17 '05 #9
> (There is also at least a vtable, and probably other junk. Suffice to say that the member data isn't all there is.)

OK... that was stupid of me. The vtable is part of the class
definition. There's no need to have a separate vtable for each instance
of a class, so there is probably only one vtable per class stored
somewhere. Every instance of a class contains a pointer back to that
class's shared information, of which the vtable would logically be a
part.

Nonetheless, there must at least be some marker in the instance's
allocated heap space saying what kind of object it is, so that you can
get back to the global class information and the vtable.

Nov 17 '05 #10

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

Similar topics

8
4886
by: cpptutor2000 | last post by:
I am using an STL list to store data packets in a network simulator. The data packets are really C structs, which have other C structs inside them. These structs contain unsigned char arrays of various sizes, and some unsigned int values. There are no pointers values stored in these structs. I have a function, from inside of which I have a loop as follows: Please note that dataPacketStore is the name of the struct being stored. ...
20
12405
by: Elliot Marks | last post by:
If a struct or its members are passed to a function, must it be declared globally? #include <stdio.h> struct mystruct{ int a; int b; }; int structfunc(struct mystruct foo);
22
2095
by: Jaspreet | last post by:
I was recently asked this question in an interview. Unfortunately I was not able to answer it and the interviewer made a decision on my C strengths (or weekness) based on this single question and that was a sad end to my interview. Here is the program: #include <stdio.h> int main() { char *c ="abc";
3
5121
by: Mark | last post by:
I have a .cs file that contains a public class and a public struct in a single namespace. I decided I wanted the struct to only be accessible to the class, and not to the rest of my project. I changed the public struct to a private struct, but it gave me the following error ... why? What are my options? Thanks in advance! - Mark "Namespace elements cannot be explicitly declared as private, protected, or protected internal."
1
1451
by: Esteban Felipe | last post by:
Hi, thanks for reading. I hope to find some help here before I commit suicide because this is driving me crazy. Please excuse me if this looks like a long post, but I hope that a complete explanation help you to help me :=) ....Let's start with some background: ..- I'm building an asp.net application that requires users to upload text files in cvs format with data exported from an AS-400. ..- The files will be something between 800kb...
24
2865
by: arcticool | last post by:
I had an interview today and I got destroyed :( The question was why have a stack and a heap? I could answer all the practical stuff like value types live on the stack, enums are on the stack, as are structs, where classes are on the heap... when value types go out of scope the memory is re- allocated, object remain in memory waiting to be cleaned up by the garbage collector, etc, but he responded 'so why not just put say a class on the...
18
33877
by: Jack | last post by:
Thanks.
5
3362
by: Y2J | last post by:
I am working through this book on C++ programming, the author is speaking of using linked lists. He gave and example which I found confusing to say the least. So I rewrote the example in a way that I could better understand the concept, he was trying to convey to me. I ran my own example and it crashed and burn "what a surprise!" : (. I ran the authors example out of the book and quess what, it crashed also, : 0. I ran them both on my...
9
6521
by: AM | last post by:
Hi, I have a C++ Dll that has a function that is being exported as shown below extern "C" __declspec(dllexport) validationResult __stdcall _validateData(double dataToMat, int time); A structure is defined in the header(.h file) as shown below struct validationResult {
0
8400
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
8924
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
8823
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
7441
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
6234
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
5702
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
1
2817
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
2
2058
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
2
1814
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.