CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5
  1. #1
    Join Date
    Jun 2013
    Posts
    2

    Memory Address of Class Member Variables

    Hello,

    Suppose I have two classes, MyClassX and MyClassY, each with two member variables, as defined below. I create an object instance of each class, and then create a pointer to each member variable for each object:

    Code:
    class MyClassX
    {
    public:
    
    	int a;
    	double b;
    
    	MyClassX(int _a, double _b)
    	{
    		a = _a;
    		b = _b;
    	};
    };
    
    
    class MyClassY
    {
    public:
    
    	int a;
    	int b;
    
    	MyClassY(int _a, int _b)
    	{
    		a = _a;
    		b = _b;
    	};
    };
    
    
    int main()
    {
    	MyClassX x(1, 2.0);
            void* pxa = &x.a;
    	void* pxb = &x.b;
            int sx = sizeof(MyClassX);
    
    	MyClassY y(1, 2);
            void* pya = &y.a;
    	void* pyb = &y.b;
            int sy = sizeof(MyClassY);
    
            return 0;
    }

    The address I get are:

    pxa = 20ef38
    pxb = 20ef40

    pya = 20ef78
    pyb = 20ef7c

    And the class sizes are:

    sx = 16.
    sy = 8.

    After converting the hexadecimal to decimal, it appears that with MyClassX, pxb is 8 bytes from pxa, whereas for MyClassY, pya is only 4 bytes from pyb. This makes sense for MyClassY, because the first member variable to be stored is an int, and so will occupy 4 bytes. However, why should this be any different for MyClassX, which also has an int as the first member variable, so shouldn't this also occupy 4bytes?

    The reason I have come across this problem is that I am looking into streaming objects to memory and then loading them again. (I know boost can do this, but I am trying it out myself from scratch.) Therefore, this is causing an issue, because I cannot just assume that the size of memory occupied by an object is just the sum of the sizes of its member variables. MyClassX is 8 bytes larger than MyClassY, even though the intuition is that it should only occupy 4 bytes more due to a double being replaced by an int.

    Thanks for any help!

  2. #2
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Memory Address of Class Member Variables

    I cannot just assume that the size of memory occupied by an object is just the sum of the sizes of its member variables.
    Corrrect! c++ can also store additional info in the class such as virtual pointers etc.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  3. #3
    Join Date
    Jun 2013
    Posts
    2

    Re: Memory Address of Class Member Variables

    Ok, thanks. But is it safe to assume that every instance of a class will occupy the same memory? i.e. these virtual pointers etc. will be consistent across all instances?

  4. #4
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Memory Address of Class Member Variables

    Yes. sizeof(classname) or sizeof(classinstance) will give the same result as sizeof(..) is evaluated at compile time. The compiler determines the layout and hence the size of the class at compile time and this doesn't change during program execution.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  5. #5
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Memory Address of Class Member Variables

    Quote Originally Posted by 2kaud View Post
    Corrrect! c++ can also store additional info in the class such as virtual pointers etc.
    There will typically only be a single vtable pointer in a class regardless of how many virtual functions there are, so you can expect a class to grow by the size of a single pointer if it has virtual functions
    However this isn't guaranteed, it is possible that this doesn't affect the sizeof().
    virtual multiple inheritance may or may not affect this further, and other meta data in the class (runtime type information) can have an effect on the sizeof as well.

    However, why should this be any different for MyClassX, which also has an int as the first member variable, so shouldn't this also occupy 4bytes?
    you're getting padding bytes after the int in the 1st class to make sure the double is aligned on an 8byte boundary.

    you will want to set an explicit packing (this is compiler dependant, VS does it with #pragma pack) to make sure no header has changed this to something unexpected and forgot to restore it.


    The reason I have come across this problem is that I am looking into streaming objects to memory and then loading them again.
    if you want to stream a class... provide a virtual load/save (or saveload(bool bSave)) or << and >> operators or whatever explicitely and stream individual members there.
    Do not assume that in any shape or form you can get a reliable and generic save/load for all cases by saving(loading) sizeof() bytes starting at the address of the class instance.

    it can work for pure data classes if you don't use inheritance. Anything else may not be portable across platforms, or even across versions of the same compiler brand.

    besides, if you store something like a std::string or MFC CString, then the string pointed to won't even be part of the sizeof of your class, so you need "special" code for this case anyway. The same holds for any pointers or references or containers in your class.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured