CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 15
  1. #1
    Join Date
    Feb 2001
    Posts
    872

    embedded class and memory layout

    I have one class embedded in another class... For my application, I need to know the memory layout of the class.

    For example:
    class CA
    {
    int nX;
    int nY;
    CNode Node;
    };

    main()
    {
    CA * pA = new CA;

    }

    Let's say pA = 0x00003100. How can I determine the beginning location of CA's member?

    Thanx in advance!


  2. #2
    Join Date
    Oct 2001
    Posts
    238

    Re: embedded class and memory layout

    I think nX is at same address as pA, meaning a
    pointer to class points to first member.
    Any "extras" for accurate boundaries are at end.
    Not totally sure. I guess you can always force
    a cast from class pointer to int pointer and
    inspect data(Debug) and make sure. Actually I
    I worked on a project before and used a union
    that depended on this.


  3. #3
    Join Date
    Feb 2001
    Posts
    872

    Re: embedded class and memory layout

    I'm not sure if the following can be an answer to the problem:

    offsetof(...)

    It's more flexible than hard-coding the values since if u add/remove a member u'd have to adjust the hardcoded value. Havent tried it yet though... Still working my way thru trying very hard to fix a bug (that's why programmer needs more love than normal ppl)...

    ~~ sigh ~~



  4. #4
    Join Date
    Feb 2001
    Posts
    872

    Re: embedded class and memory layout

    I am afraid yr response wont help in my situation... I need to do some buffer copy.

    And the source/destination buffer are not of the same size (It's not even the same thing/class). That's why I need exact memory layout within a class.


  5. #5
    Join Date
    May 2000
    Location
    KY, USA
    Posts
    18,652

    Re: embedded class and memory layout

    Memory layout is always an implentation issue, a common approach is as follows:

    class A
    {
    public:
    int m_Int;
    };

    class B
    {
    public:
    long m_Long;
    };

    class C
    {
    public:
    double m_Double;
    };



    The layout for class A would be:

    - Pointer to virtual table A
    - Integer 'm_Int'


    The layout for class B derived from class A (class B : public A):

    - Pointer to virtual table B (first entries in this table are inherited/overriden virtual functions of A)
    - Integer 'm_Int'
    - Long 'm_Long'


    The layout for class C derived from class A and B (class C : public A, public B):

    - Pointer to virtual table C (first entries in this table are inherited/overriden virtual functions of A)
    - Integer 'm_Int'
    - Pointer to virtual table C (first entries in this table are inherited/overriden virtual functions of B)
    - Integer 'm_Int' from class B
    - Long 'm_Long'
    - Double 'm_pDouble'


    In the last case 'm_Int' is replicated twice. To avoid this use virtual inheritence:

    class B : public virtual A
    class C : public virtual A, public B

    Now the layout for class C - if I recall correctly:

    - Pointer to virtual table C (first entries in this table are inherited/overriden virtual functions of A)
    - Integer 'm_Int'
    - Pointer to 'm_Int'
    - Integer 'm_Int'
    - Pointer to virtual table C (first entries in this table are inherited/overriden virtual functions of B)
    - Pointer to 'm_Int'
    - Integer 'm_Int' (never used)
    - Long 'm_Long'
    - Double 'm_Double'



    Ciao, Andreas

    "Software is like sex, it's better when it's free." - Linus Torvalds

  6. #6
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: embedded class and memory layout

    You should never use memcpy() for a class because its members may have internal pointers and you will be copying those pointers without allowing the class to call its assignment function, which may well either create a new pointer or increase the reference count.

    Then when it comes to delete its members it could delete the same piece of memory twice, or could be deleting too early (while the other instance is still active).

    In addition, you should know that a class member will often have a hidden pointer to its v-table, even if you set pack to 1 with #pragma pack. And if you don't set it that way, it will normally align so a WORD starts on an even number byte and a DWORD or a pointer to an byte divisible by 4.

    Better to write a proper copy constructor and operator=


    The best things come to those who rate

  7. #7
    Join Date
    Feb 2001
    Posts
    872

    Re: embedded class and memory layout

    oops. Although I havent quite digested yr advice yet, i seems to me though that this is going to be a big problem for my project...

    Let's see if I can post a code snippet today to see if we understand each other argument...

    Thanx though.


  8. #8
    Join Date
    Feb 2001
    Posts
    872

    offsetof(CMyClass, m_data_member);

    I think offsetof(..) is going to solve the problem...

    Implementation in progress... Hope this will work. Dont see any reason why it shouldnt yet... Even if inheritance is involved and the class memory profile begins with a virtual function table pointer, this function should (havent tested that) be able to adjust accordingly... This is NOT covered in its documentation in MSDN though.

    Thanx and hope to get more feedback from u guys while I'm doing the testing today.


  9. #9
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: offsetof(CMyClass, m_data_member);

    I'd need to see the context in which you are using it.

    You can always do

    &(myClass.member)

    or

    &(pMyClass->member)

    to get a pointer to the member

    You can then use ptrdiff_t to subtract the two pointers and get an offset.

    That's probably all offsetof (which is a macro) does anyway.


    The best things come to those who rate

  10. #10
    Join Date
    May 2000
    Location
    KY, USA
    Posts
    18,652

    Re: offsetof(CMyClass, m_data_member);

    'offsetof()' is only a macro defined the following way

    #define offsetof(s,m) (size_t)&(((s *)0)->m)



    It will skip virtual table pointers...consider the following example

    class CFoo
    {
    public:
    int i;
    char *p;
    double d;

    void f();
    };

    int main()
    {
    cout << offsetof(CFoo, d);

    return 0;
    }



    The output will be 8 on a windows system...

    Ciao, Andreas

    "Software is like sex, it's better when it's free." - Linus Torvalds

  11. #11
    Join Date
    Feb 2001
    Posts
    872

    Re: offsetof(CMyClass, m_data_member);

    Quote:

    You can always do

    &(myClass.member)

    or

    &(pMyClass->member)


    I think I really made simple things way too complicated... And yes, this is exactly all that I need.

    Sorry guys!


  12. #12
    Join Date
    Dec 2001
    Posts
    191

    Re: embedded class and memory layout

    MFC's implementation of activeX depends on this (calculating embedded class offsets), and just uses pointer differences (as mentioned in other posts already present).

    (Note: I did not say Microsoft's implementation of activeX -- I said MFC's.)


  13. #13
    Join Date
    Oct 2001
    Location
    CA,USA
    Posts
    60

    A quick question


    Is there a way where i can call a function in
    a class without using the name of the function.

    class A
    {
    public :
    int x
    void print(){cout<<"Hello";}
    };

    A *a;
    then using this pointer call print function
    without using the name. I dont want to use
    a->print();

    I am in this situation beacuse i have the name of the function in database. using that name and the name of the class i want to call the function.




    Please rate the article if it is of any use to you. This encourages me to reply more and more and more.

  14. #14
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: A quick question

    yes, that is called a member function and it has a signature something like this:

    void (*A::fn)(void);



    (I can't remember for certain, I don't have all my references with me).

    That function can only be called if you have an instance of A (pointer, reference, whatever).

    Note that as your function is not declared const, it cannot be a const reference or pointer. To do that you need to put a const after the function prototype and before the semicolon.

    If you don't want your function to refer to any members of A, then you can make it static and you can pass the function pointer like any other.

    An alternative (perhaps the more object-orientated method) is to use a class. You can give the class no member variables at all, just functions. And if you make these functions virtual then you can obviously change the functions that they will execute. Each class instance will be the size of one pointer, the pointer to its v-table.



    The best things come to those who rate

  15. #15
    Join Date
    Feb 2002
    Posts
    81

    Re: embedded class and memory layout

    Here is how to display it:


    std::cout<<std::hex<<reinterpret_cast<void*>(pA->Node);





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