Accessing Structure Members With 'sizeof( )'

closed account (zb0S216C)
It's possible to get member( not methods ) data from a structure by using sizeof( ). However, when it comes to accessing the next member in the list, I can't seem to get to it. Allow me to show you how I do this. Below is my code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>

using std::cout;
using std::cin;
using std::endl;

struct STRUCTURE
{
    STRUCTURE( void ) : MemberOne( 10 ), MemberTwo( 3.4f ) { }
    int MemberOne;
    float MemberTwo;
} Structure;

int main( )
{
    int MemberOne_Buffer( 0 );
    memcpy( &MemberOne_Buffer, &Structure, sizeof( int ) );

    cout << "Structure.MemberOne = " << MemberOne_Buffer << endl;     

    cin.get( );
    return 0;
}

Running this code gives:
Structure.MemberOne = 10


Here's the thing: I don't know how I should go about fetching the value of MemberTwo. Any suggestions?

P.S: I know this may seem pointless but I'm just experimenting.
Last edited on
closed account (zwA4jE8b)
I don't know if this is legal but maybe adding sizeof int to the address will put you where you need to be.


memcpy( &MemberOne_Buffer, &Structure + sizeof( int ), sizeof( int ) );

or
memcpy( &MemberOne_Buffer, &(Structure + sizeof( int )), sizeof( int ) );

maybe, just a guess....
closed account (zb0S216C)
It compiles but gives me 0, not 3.4f. Maybe I need to get the entire size of STRUCTURE then divide it by the size of each element?
Last edited on
The bigger question is: Why on earth do you want to do this?

You need to cast &Structure to char*, then add sizeof( int ), however you're well into undefined behavior / compiler implementation dependent behavior at that point.


Did you try making the last parameter sizeof( float ) instead of size of int? Something like:
memcpy(&MemberTwo_Buffer, (&Structure) + sizeof( int ) /* offset from first member */, sizeof( float ) /* size of member we are copying */);
If you want to do pointer math like this you need to convert to a char pointer. The reason for this is illustrated below:

1
2
3
4
5
int* foo = new int[10];
int* a = &foo[1];
int* b = foo + 1;

// note:  a == b 


Therefore if you do this:

1
2
3
SOMESTRUCT s;

ptr = &s + sizeof(int);


You're actually pulling from a different (nonexistant) struct. Same as if you were doing this:

 
ptr = &s[ sizeof(int) ];



Therefore if you want to get members within the struct, you could (BUT SHOULDN'T) do this:

1
2
3
4
5
6
STRUCTURE s;
char* p = reinterpret_cast<char*>(&s); // make it a char pointer
  // this way pointer math increments by bytes instead of by sizeof(struct)s

float afloat;
memcpy( &afloat, p + sizeof(int), sizeof(afloat) );



Of course.... this comes with the expected disclaimers:

1) This is atrociously messy
2) As you can see, it's dangerous unless you're very careful
3) It isn't even guaranteed to work because the compiler can rearrange that struct however it wants, add padding, etc in order to make accessing members more efficient.
4) There's no point to doing this because you can just access members the "normal way".


EDIT: man I was way too slow =(
Last edited on
closed account (zb0S216C)
Jsmith, I did say that I was experimenting. It doesn't mean that I will be implementing it in future projects.

I did what you said, Jsmith. I've added the following line and now it prints 3.4:
1
2
3
4
5
// ...
float MemberTwo_Buffer( 0.0f );
memcpy( &MemberTwo_Buffer, ( char * )&Structure + sizeof( float ), sizeof( float ) );

cout << "Structure.MemberTwo = " << MemberTwo_Buffer << endl;


Now prints:
Structure.MemberTwo = 3.4


Edit -----------------------------------------8<-------------------------------------
Zhuge, I understand where you're coming from about displacing the offset, but I already tried that to no avail.

Disch, thank you for your explantion. It helped me quite a lot. I can say that Disch, and Jsmith made me realise that accessing structure members with sizeof( ) is more volatile than I previously thought.

Thanks for your replies. I really should nuke my HDD to get rid of this demonic code :)

Thanks again.

Last edited on
Take a look below. Don't mess with the memcpy stuff if you don't have to.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
include <iostream>

using std::cout;
using std::cin;
using std::endl;

struct STRUCTURE
{
    STRUCTURE( void ) : MemberOne( 10 ), MemberTwo( 3.4f ) { }
public:
    int MemberOne;
    float MemberTwo;
public:
    void SetMemberOne(int m1)
        { MemberOne = m1; }
    void SetMemberTwo(float m2)
        { MemberTwo = m2; }
} Structure;

int main( )
{
    int MemberOne_Buffer( 0 );
    float MemberTwo_Buffer( 2.0 );
//do this
    Structure.MemberOne = MemberOne_Buffer;
    Structure.MemberTwo = MemberTwo_Buffer;
//or this
    Structure.SetMemberOne(MemberOne_Buffer);
    Structure.SetMemberTwo(MemberTwo_Buffer);
//of if you insist.
    memcpy( &MemberOne_Buffer, &(Structure.MemberOne), sizeof( int ) );
    memcpy( &MemberTwo_Buffer, &(Structure.MemberTwo), sizeof(float) );

    cout << "Structure.MemberOne = " << MemberOne_Buffer << endl;     

    cin.get( );
    return 0;
}
Topic archived. No new replies allowed.