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!
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.
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 ~~
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.
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
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
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.
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.
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
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
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!
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.)
Re: embedded class and memory layout
Here is how to display it:
std::cout<<std::hex<<reinterpret_cast<void*>(pA->Node);