2010-10-11 2 views
0

Я получаю неправильное значение при доступе к variabel v2, используя их расположение памяти, когда HWND перед переменной bool. Если Ii использует HWND после bool, тогда я получаю правильный результат. Использование переменной экземпляра (t) Я получаю правильное значение для v1 и v2, таких как t->v1 и t->v2. Я использую Windows Server 2003. У меня есть следующий класс Test. это только воспроизводится в 64-битной ОС; 32-разрядная ОС отлично работает.Доступ к переменной через ячейку памяти

#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; 
} 

ответ

2

Вы, кажется, предположить, что ваш v1 и v2 должны находиться именно в конце объекта типа Test. Это совершенно необоснованное предположение. Язык не дает таких гарантий, и в общем случае они не будут. Объект, как правило, заканчивается байтами заполнения. Эти байты заполнения - это то, что вы на самом деле читаете в своем коде. Неудивительно, что они содержат мусор.

Добавочные байты добавляются к объектам, чтобы удовлетворить их требования к выравниванию. Поскольку требования к выравниванию могут (и будут) меняться при переключении с 32-разрядного режима на 64-разрядный, неудивительно, что при компиляции кода в разных режимах вы получаете разные результаты.

2

Компилятор позволяет добавлять простыню где угодно, чтобы получить наиболее эффективные адреса и размеры. Он не может добавлять дополнение к первому члену в структуре POD, простые старые данные, но ваш класс не POD (у него есть конструктор). Что вы можете сделать, чтобы понять это, так это удалить конструктор, чтобы у вас был POD, и использовать макрос offsetof стандартной библиотеки, чтобы проверить, где именно находятся элементы в структуре.

Приветствия & НТН,

-. Альф

Смежные вопросы