say you do....

struct test {
int one;
int two;
someotherstruckt testthree;
dword four;
};

How would that be stored in memory?
DWORD DWORD DWORD DWORD ? or DWORD DWORD BYTE*Sizeof(someotherstruckt) DWORD ?
Posted on 2003-08-01 14:32:11 by SFP
If you had (in ASM not C format):
SomeStruct STRUCT

Test1 DWORD ?
Test2 DWORD ?
SomeStruct ENDS

SomeOtherStruct STRUCT
Test1 DWORD ?
Test2 DWORD ?
Test3 SomeStruct <>
Test4 DWORD ?
SomeOtherStruct ENDS

it would be stored as follows
SomeOtherStruct.Test1 ; Offset 0
SomeOtherStruct.Test2 ; Offset 4
SomeOtherStruct.SomeStruct.Test1 ; Offset 8
SomeOtherStruct.SomeStruct.Test2 ; Offset 12
SomeOtherStruct.Test4 ; Offset 16
If it was a union :
SomeOtherStruct STRUCT

Test1 DWORD ?
Test2 DWORD ?
UNION
Test3 DWORD ?
Test4 WORD ?
ENDS
Test5 DWORD ?
SomeOtherStruct ENDS

it would be stored as follows
SomeOtherStruct.Test1 ; Offset 0
SomeOtherStruct.Test2 ; Offset 4
SomeOtherStruct.Test3 ; Offset 8 >>> all offsets in the union are equal
SomeOtherStruct.Test4 ; Offset 8
SomeOtherStruct.Test5 ; Offset 12 >>> The offset of this member is fixed using the largest union member
Posted on 2003-08-01 14:54:47 by donkey
FYI: Depending on your compiler settings structure members might be aligned to their own size.. This is usally done by default (improves performance). This means that struct blah { char c; int b;} does not take 5 but 8 bytes, because 'b' is aligned on 4 byte boundaries.

Thomas
Posted on 2003-08-01 15:18:03 by Thomas
The compiler is MSVC 6....

So if I did
struct dumb {
dword test;
dword testtwo;
} MyStruct;
struct test {
int testone;
dword testtwo;
MyStruct dumbstruct;
}
it would be stored as
struct test... ->
int testone (dword)
dword testtwo (dword)
dword test (dword)
dword testtwo (dword)
in memory? Mark that I'm using the MyStruct in test and not the struct name...
Posted on 2003-08-01 15:38:36 by SFP

FYI: Depending on your compiler settings structure members might be aligned to their own size.. This is usally done by default (improves performance). This means that struct blah { char c; int b;} does not take 5 but 8 bytes, because 'b' is aligned on 4 byte boundaries.

Thomas

That's true, for MASM the default allignment is 1 but you can over-ride it on a case by case basis using the alignment directive for structures...
SomeOtherStruct STRUCT [b]DWORD[/b] ; [i]Align all members on a DWORD boundary[/i]

Test1 DWORD ?
Test2 DWORD ?
Test3 WORD ?
Test4 DWORD ?
SomeOtherStruct ENDS

would be stored as follows
SomeOtherStruct.Test1 ; Offset 0
SomeOtherStruct.Test2 ; Offset 4
SomeOtherStruct.Test3 ; Offset 8
SomeOtherStruct.Test4 ; Offset 12 even though it appears in the 10th byte of the struct
Posted on 2003-08-01 15:51:01 by donkey

The compiler is MSVC 6....

So if I did
struct dumb {
dword test;
dword testtwo;
} MyStruct;
struct test {
int testone;
dword testtwo;
MyStruct dumbstruct;
}
it would be stored as
struct test... ->
int testone (dword)
dword testtwo (dword)
dword test (dword)
dword testtwo (dword)
in memory? Mark that I'm using the MyStruct in test and not the struct name...


Well actually that wouldn't even compile.. You can't use MyStruct as a type because it isn't. Dumb is the type, MyStruct is an instance of the dumb structure. This would compile:


struct dumb
{
DWORD test;
DWORD testtwo;
};

struct test
{
int testone;
DWORD testtwo;
dumb dumbstruct;
};

And that would be in memory like you said. Because all members are 4 bytes there's no padding while they're still aligned.

Thomas
Posted on 2003-08-01 16:18:29 by Thomas
ok thx.
Posted on 2003-08-01 16:21:28 by SFP
Ok, i will try some.. if you know this sorry ;) is for understand a little more what is a struct or union...


ok, at the end (maybe not the very end in that wee have electric circuit and phisic and quimic.. atoms..... ummm??)... ok, returning from this... at the end the programms are stored in memory and executed, but also the space in memory are unidirectional in some way for simplicity 0 to n, then the instructions and the data are stored there in a sucesive form then you have a lot of numbers for acces this address, then if you code some like: (in C like you are saying)

int testone; /*(dword)*/
dword testtwo; /* (dword)*/
dword test; /* (dword)*/
dword testtwo;

there will be stored in a sucesive way in the space of data.. or in rare cases in the place of code (later in the stack, but always in memory).

My gues is if you obtain the direction of the first int (testone) and you move to the next space (ifyou want a cast) you can go troguht the memory and access the sucesive spaces, but in this way you can acces the other directions, ok if you can do this manually... for what you need a struct or union?????

Is a little simple, you can organize more the address space to a 'look and feel' that you want and not only address, I dont know if structs/unions can be called abstract data types, but I think they are..., and can be more easely used that do it yourself, for example:


x = (int *) malloc (18);

In this way you have the same space of the anterior example, but for acces the specific offset you need make some additions and subtractions.. or the called pointer arithmetic, based on the base address add 0 for acces the first member, add 4 for the second, add 8 for the 3 and 12 for the 4th element, remember total size 16.. and now you are organized the memory in a way that you like...., but for acces you need make additions and suchs thins to a pointer...

Ok.. here comes the struct (first)
you DEFINE how a structure will look of a specific type.. that make sense for your problem and your point of view!!!!

typedef struct some some;
struct some{
int a;
int b;
};
some xx;

you cann see this like:

make me a label called 'xx' then reserve for me the size of struct some (in this case posible 8??), then mark the first member with offset 0 and the second member to offset 4. And when you do mov eax, , you are doing move eax, and mov eax, like mov eax, , then you see that with struct/(unions) you are interpretating the address space like you want, this can be easely translated to stack locals instead on the label they will be defined some like:

ebp - offsetInTheStack + offsetInTheDefinitionOfTheStructure


and offsetInTheStack and offsetInTheDefinitionOfTheStructure are constant, then they can be easely added or substracted by the assenbler, and then this will be some like ebp-20

Ok.. only a last thing.. the diference between the data types structs and unions... is not much...;

the struct the specific offset is always added to the anterior, and the size grow up for the members contained, and the unions, all the offset are the same of the first and the total size is the maxime size of a respective member.


1) remember, for data the "steps" can be thinked as:

define a label. Reserve the space. Make the offsets.

2) For locals (in the stack)

Reserve the space including all the other locals in thescope (some like add ebp, -54), instead of the label use a combination of ebp-offset, Make the offsets.

3) In the heap or other is very ner to 2), but instead of based from a specific location (like 1) or a register (like 2) is a addres returned from a function in the heap or some where in the addresss space.

And at the end for 1) and 2) , 3) the acces is only add the respective offsets of the members.

Have nice day.
Posted on 2003-08-01 21:22:42 by rea
struct dumb
{
DWORD t;
DWORD e;
};

struct test
{
int o;
DWORD n;
dumb d;
};

this struct test would be in memory as
[][][][] test.o
[][][][] test.n
[][][][] test.d.t
[][][][] test.d.e
//-----------------------------------------------------
struct dumb
{
DWORD t;
DWORD e;
};

struct test
{
int o;
DWORD n;
dumb* d;
};
in test member d would have to be set with a pointer to a struct dumb
test.d =(dumb*)&Ddumb
[][][][] test.o
[][][][] test.n
[][][][] test.d->
...
...
...
[][][][] test.d->t
[][][][] test.d->e
hope this helps.
Posted on 2003-08-01 23:55:29 by Qages
I've been looking at some other peoples code now and watching how that looks like in memory, they are typedefing the structs like

struct test {
dword ok;
}
typedef test mytest;

then they are doing

struct anothertest {
int o;
mytest yes;
};

That seems to make the second dword of anothertest an address though.
Posted on 2003-08-02 09:32:02 by SFP