开发者

Access variable through memory location

I get wrong value when accessing variabel v2 using their memory location when HWND is before bool variable. If Ii use HWND after bool then I get correct result. Using instance variable (t) I get correct value for v1 and v2 such as t->v1 and t->v2. I am using Windows开发者_如何学C Server 2003. I have the following Test class. this is only reproducible in 64 bit OS; 32 bit OS work fine.

#include "conio.h"
#include "stdio.h"
include "windows.h"
class Test
{
public :
 Test()
 {
  v1=12345678;
  v2=87654321;
 }

 HWND        hWnd;
 bool        MsgHandled;



 unsigned long v1;
 unsigned long v2;

};

int _tmain(int argc, _TCHAR* argv[])
{
 Test* t=new Test();
 unsigned long sign1 = *(unsigned long*)((unsigned char*)t + sizeof(Test)-2*sizeof(unsigned long));
 unsigned long sign2 = *(unsigned long*)((unsigned char*)t + sizeof(Test)-sizeof(unsigned long));

 printf("\nTest size %d",sizeof(Test));

 printf("\n t->v1 %d",t->v1);
 printf("\n t->v2 %d",t->v2);

 printf("\n v 1 %d",sign1);
 printf("\n v 2 %d",sign2); // garbage value in 64 bit os

 getch();
 return 0;
}


You seem to assume that your v1 and v2 must reside precisely at the end of the object of type Test. This is a completely unfounded assumption. The language makes no such guarantees and in general case they will not. The object will generally end with padding bytes. These padding bytes is what you are actually reading in your code. No wonder they contain garbage.

Padding bytes are added to objects in order to satisfy their alignment requirements. Since the alignment requirements can (and will) change when switching from 32-bit mode to 64-bit mode, it is not surprising that you get different results when compiling your code in different modes.


The compiler is allowed to add padding just about anywhere in order to get addresses and sizes that are most efficient. It can't add padding before the first member in a POD struct,plain old data, but your class isn't POD (it has a constructor). What you can do to understand this is to remove the constructor -- so that you have a POD -- and use the standard library's offsetof macro to check where exactly the members are placed within the struct.

Cheers & hth.,

– Alf

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜