VS2010 x64:64 位平台 VS2010 中包含错误数据的对象数组
VS2010 x64: Array of objects containing wrong data in 64-bit platform VS2010
我正在将 32 位代码移植到 VS2010 中的 64 位代码。尝试启动其中一个对话框时,我的应用程序崩溃了,但我发现它在 32 位配置中运行良好,但在 64 位配置中运行不佳。我发现有一个包含字符数组的对象数组,数据在 64 位平台上不正确。例如。假设有一个字符串列表:red, black,....在 32 位中,列表显示正确,但在 64 位中,第二个对象的字符指针指向黑色的 k,即比实际数据提前 4 个字节。对象大小在 32 位平台中为 144 字节,但在 64 位平台中每个对象为 148 字节。
BOOL SomeDlg::OnInitDialog( HWND hwnd, HWND hwndFocus, LPARAM lParam )
{
MEMBERASSERT();
CABCDialog::OnInitDialog( hwnd, hwndFocus, lParam );
int nHeight = ListBox_GetItemHeight( GetDlgItem(hwnd, IDC_DUMMYLIST), -1 );
m_myLst.SetItemHeight(-1, nHeight);
m_ClrLst.SetItemHeight(-1, nHeight);
char smyItem[64];
for (UINT i=0; i < 10; i++)
{
LoadString(g_hInstance, IDS_COLORNAMES+i, smyItem, ELEMENTS_IN(smyItem));
m_ZAItems[i].SetColor(m_pSettings->m_rgbColors[i]);
m_ZAItems[i].SetText(smyItem);
//debug issue, check size of object
int a = sizeof(m_ZAItems[i]);
m_myLst.AddItem( &m_ZAItems[i] );
}
//some other stuff
}
class SomeDlg : public CABCDialog
{
private:
MyDrwaLstBox m_myLst;
My_ColorComboBox m_ClrLst;
My_ColorText m_ZAItems[11];
private:
SomeDlg();
SomeDlg(const SomeDlg &);
const SomeDlg &operator=(const SomeDlg &);
public:
SomeDlg(HWND hwndZW, MCURRENT* pSettings , LPCSTR szName );
virtual void Notification( ADM_Wnd *pWnd, UINT uID, int nNotificationCode, LPARAM lData );
virtual BOOL OnInitDialog( HWND hwnd, HWND hwndFocus, LPARAM lParam );
};
class MyDrwaLstBox : public MY_ListBox
{
protected:
BOOL m_bpmn;
private:
MyDrwaLstBox( const MyDrwaLstBox& );
const MyDrwaLstBox & operator=( const MyDrwaLstBox & );
public:
MyDrwaLstBox ();
virtual void OnDrawItem( HWND hwnd,
const DRAWITEMSTRUCT * lpDrawItem );
};
class My_ColorText : public My_Color
{
private:
enum { txtLen = 128 };
TCHAR m_szText[ txtLen ];
My_ColorText ( const My_ColorText & );
const My_ColorText &operator=( const My_ColorText & );
public:
My_ColorText ();
My_ColorText ( COLORREF rgbColor, LPCTSTR pszText );
void SetText( LPCTSTR pszText );
void SetText( HINSTANCE hInstance, UINT uID );
LPCTSTR GetText();
virtual void Draw( HDC hDC, RECT rRect, BOOL bChecked, BOOL bDisabled,
BOOL bFocus, BOOL bGrayed, BOOL bSelected );
};
My_ColorText::My_ColorText()
{
m_szText[0] = '[=10=]';
}
My_ColorText::My_ColorText( COLORREF rgbColor, LPCTSTR pszText )
: My_Color( rgbColor )
{
MDC_strncpyz( m_szText, pszText );
}
void My_ColorTex::SetText( LPCTSTR pszText )
{
MDC_strncpyz( m_szText, pszText );
}
void My_ColorText::SetText( HINSTANCE hInstance, UINT uID )
{
*m_szText = '[=10=]';
LoadString( hInstance, uID, m_szText, ELEMENTS_IN( m_szText ) );
}
LPCTSTR My_ColorText::GetText()
{
return m_szText;
}
template <size_t size>
LPSTR MDC_strncpyz(CHAR (&dest)[size], LPCSTR srce) { return MDC_strncpyz(dest, srce, size); }
class My_Color : public My_DrawItem
{
private:
COLORREF m_rgbColor;
private:
My_Color( const My_Color & );
const My_Color & operator=( const My_Color & );
public:
My_Color( void );
My_Color( COLORREF rgbColor );
virtual void Draw( HDC hDC,
RECT rRect,
BOOL bChecked,
BOOL bDisabled,
BOOL bFocus,
BOOL bGrayed,
BOOL bSelected );
};
My_Color::My_Color void )
: m_rgbColor( RGB_BLACK )
{
}
My_Color::My_Color( COLORREF rgbColor )
: m_rgbColor( rgbColor )
{
}
class My_DrawItem
{
protected:
BOOL m_bInListBox;
DWORD m_dwUser;
private:
My_DrawItem( const My_DrawItem & );
const My_DrawItem & operator=( const My_DrawItem & );
public:
My_DrawItem();
virtual ~My_DrawItem();
virtual void Draw( HDC hDC,
RECT rRect,
BOOL bChecked,
BOOL bDisabled,
BOOL bFocus,
BOOL bGrayed,
BOOL bSelected );
};
My_DrawItem::My_DrawItem()
: m_bInListBox( FALSE ),
m_dwUser( 0 )
{
}
'SomeDlg' class 包含 My_ColorComboBox class 的对象,后者又包含 class My_ColorText 的对象数组。
当 My_ColorText class 的构造函数通过 My_ColorComboBox class 调用时,m_ColorItems[0] 的 m_szText 和 [= 的基地址不同22=][1]的m_szText等于152字节。意味着 My_ColorText() 构造函数为 m_szText 变量分配基地址,相差 152 个字节。
但是当通过 SomeDlg class 调用 My_ColorText class gest 的构造函数时,m_ZAItems[0] 的 m_szText 和 m_ZAItems 的基地址不同[1]的m_szText等于148字节。因此,字符串没有被插入到相差 152 字节的正确位置。
当我检查 sizeof(My_ColorText) 时,在这两种情况下它都给了我 152 个字节。
我在堆上创建了对象,而不是在堆栈上创建。
添加了以下行以解决问题。
for (UINT i=0; i < 10; i++)
{
LoadString(g_hInstance, IDS_COLORNAMES+i, smyItem, ELEMENTS_IN(smyItem));
//m_ZAItems[i].SetColor(m_pSettings->m_rgbColors[i]);
//m_ZAItems[i].SetText(smyItem);
myLst.AddItem( new My_ColorText( m_pSettings->m_rgbColors[i], smyItem ) );
}
我正在将 32 位代码移植到 VS2010 中的 64 位代码。尝试启动其中一个对话框时,我的应用程序崩溃了,但我发现它在 32 位配置中运行良好,但在 64 位配置中运行不佳。我发现有一个包含字符数组的对象数组,数据在 64 位平台上不正确。例如。假设有一个字符串列表:red, black,....在 32 位中,列表显示正确,但在 64 位中,第二个对象的字符指针指向黑色的 k,即比实际数据提前 4 个字节。对象大小在 32 位平台中为 144 字节,但在 64 位平台中每个对象为 148 字节。
BOOL SomeDlg::OnInitDialog( HWND hwnd, HWND hwndFocus, LPARAM lParam )
{
MEMBERASSERT();
CABCDialog::OnInitDialog( hwnd, hwndFocus, lParam );
int nHeight = ListBox_GetItemHeight( GetDlgItem(hwnd, IDC_DUMMYLIST), -1 );
m_myLst.SetItemHeight(-1, nHeight);
m_ClrLst.SetItemHeight(-1, nHeight);
char smyItem[64];
for (UINT i=0; i < 10; i++)
{
LoadString(g_hInstance, IDS_COLORNAMES+i, smyItem, ELEMENTS_IN(smyItem));
m_ZAItems[i].SetColor(m_pSettings->m_rgbColors[i]);
m_ZAItems[i].SetText(smyItem);
//debug issue, check size of object
int a = sizeof(m_ZAItems[i]);
m_myLst.AddItem( &m_ZAItems[i] );
}
//some other stuff
}
class SomeDlg : public CABCDialog
{
private:
MyDrwaLstBox m_myLst;
My_ColorComboBox m_ClrLst;
My_ColorText m_ZAItems[11];
private:
SomeDlg();
SomeDlg(const SomeDlg &);
const SomeDlg &operator=(const SomeDlg &);
public:
SomeDlg(HWND hwndZW, MCURRENT* pSettings , LPCSTR szName );
virtual void Notification( ADM_Wnd *pWnd, UINT uID, int nNotificationCode, LPARAM lData );
virtual BOOL OnInitDialog( HWND hwnd, HWND hwndFocus, LPARAM lParam );
};
class MyDrwaLstBox : public MY_ListBox
{
protected:
BOOL m_bpmn;
private:
MyDrwaLstBox( const MyDrwaLstBox& );
const MyDrwaLstBox & operator=( const MyDrwaLstBox & );
public:
MyDrwaLstBox ();
virtual void OnDrawItem( HWND hwnd,
const DRAWITEMSTRUCT * lpDrawItem );
};
class My_ColorText : public My_Color
{
private:
enum { txtLen = 128 };
TCHAR m_szText[ txtLen ];
My_ColorText ( const My_ColorText & );
const My_ColorText &operator=( const My_ColorText & );
public:
My_ColorText ();
My_ColorText ( COLORREF rgbColor, LPCTSTR pszText );
void SetText( LPCTSTR pszText );
void SetText( HINSTANCE hInstance, UINT uID );
LPCTSTR GetText();
virtual void Draw( HDC hDC, RECT rRect, BOOL bChecked, BOOL bDisabled,
BOOL bFocus, BOOL bGrayed, BOOL bSelected );
};
My_ColorText::My_ColorText()
{
m_szText[0] = '[=10=]';
}
My_ColorText::My_ColorText( COLORREF rgbColor, LPCTSTR pszText )
: My_Color( rgbColor )
{
MDC_strncpyz( m_szText, pszText );
}
void My_ColorTex::SetText( LPCTSTR pszText )
{
MDC_strncpyz( m_szText, pszText );
}
void My_ColorText::SetText( HINSTANCE hInstance, UINT uID )
{
*m_szText = '[=10=]';
LoadString( hInstance, uID, m_szText, ELEMENTS_IN( m_szText ) );
}
LPCTSTR My_ColorText::GetText()
{
return m_szText;
}
template <size_t size>
LPSTR MDC_strncpyz(CHAR (&dest)[size], LPCSTR srce) { return MDC_strncpyz(dest, srce, size); }
class My_Color : public My_DrawItem
{
private:
COLORREF m_rgbColor;
private:
My_Color( const My_Color & );
const My_Color & operator=( const My_Color & );
public:
My_Color( void );
My_Color( COLORREF rgbColor );
virtual void Draw( HDC hDC,
RECT rRect,
BOOL bChecked,
BOOL bDisabled,
BOOL bFocus,
BOOL bGrayed,
BOOL bSelected );
};
My_Color::My_Color void )
: m_rgbColor( RGB_BLACK )
{
}
My_Color::My_Color( COLORREF rgbColor )
: m_rgbColor( rgbColor )
{
}
class My_DrawItem
{
protected:
BOOL m_bInListBox;
DWORD m_dwUser;
private:
My_DrawItem( const My_DrawItem & );
const My_DrawItem & operator=( const My_DrawItem & );
public:
My_DrawItem();
virtual ~My_DrawItem();
virtual void Draw( HDC hDC,
RECT rRect,
BOOL bChecked,
BOOL bDisabled,
BOOL bFocus,
BOOL bGrayed,
BOOL bSelected );
};
My_DrawItem::My_DrawItem()
: m_bInListBox( FALSE ),
m_dwUser( 0 )
{
}
'SomeDlg' class 包含 My_ColorComboBox class 的对象,后者又包含 class My_ColorText 的对象数组。 当 My_ColorText class 的构造函数通过 My_ColorComboBox class 调用时,m_ColorItems[0] 的 m_szText 和 [= 的基地址不同22=][1]的m_szText等于152字节。意味着 My_ColorText() 构造函数为 m_szText 变量分配基地址,相差 152 个字节。 但是当通过 SomeDlg class 调用 My_ColorText class gest 的构造函数时,m_ZAItems[0] 的 m_szText 和 m_ZAItems 的基地址不同[1]的m_szText等于148字节。因此,字符串没有被插入到相差 152 字节的正确位置。
当我检查 sizeof(My_ColorText) 时,在这两种情况下它都给了我 152 个字节。
我在堆上创建了对象,而不是在堆栈上创建。 添加了以下行以解决问题。
for (UINT i=0; i < 10; i++)
{
LoadString(g_hInstance, IDS_COLORNAMES+i, smyItem, ELEMENTS_IN(smyItem));
//m_ZAItems[i].SetColor(m_pSettings->m_rgbColors[i]);
//m_ZAItems[i].SetText(smyItem);
myLst.AddItem( new My_ColorText( m_pSettings->m_rgbColors[i], smyItem ) );
}