我无法在可以显示的较小程序中复制此问题,因此我将使用屏幕截图来说明问题。
我有一个声明union和union的静态成员的类:
class
{
/* rest of the class */
union EmptyString
{
char8 m_Empty8[1];
uchar8 m_EmptyU8[1];
char32 m_Empty32[1];
};
static const EmptyString sm_emptyString;
};
// Definition
template <typename T>
const typename StringBase<T>::EmptyString
StringBase<T>::sm_emptyString = { 0 };
然后我有一个返回字符串地址的函数。出于调试目的,我添加了变量address
,以便我可以将其添加到监视窗口。这是函数(T
这里是char8
,其中char8
是char
的typedef:
template <typename T>
const char8* StringBase<T>::GetEmptyString( char8 )
{
const char8* address = sm_emptyString.m_Empty8;
//const char8* address = &(sm_emptyString.m_Empty8[0]);
return address;
//return sm_emptyString.m_Empty8;
}
正如你所看到的,最初我有一个return语句,我注释掉了,以便我可以调试代码片段。注释掉的另一行是获取数组的第一个(也是唯一的)元素的地址;这个注释掉的行与之前的行相同,即:const char8* address = sm_emptyString.m_Empty8;
。
程序崩溃是因为我没有通过上面的功能得到正确的地址,这让我很难过。下面我将开始调试会话的屏幕截图:
上面,你可以看到我在地址被复制到指针之前就破坏了。以下是此休息时sm_emptyString
和address
的观察窗口值。
到目前为止,没什么特别的。以下是踩过一行代码后的屏幕截图。
以及相应的观察窗口:
如您所见,复制到address
的值是错误的。另外需要注意的是,此函数被调用几次,静态变量地址的副本为address
是正确的。当地址不正确并由函数返回时,我的程序崩溃(因为程序中稍后对地址的假设)。
这里发生了什么?我在某处写过记忆吗?我该如何调试呢?
编辑:
反汇编(根据调试器,sm_emptyString
的地址为129F184
,与反汇编显示的128F134
不同):
template <typename T>
const char8* StringBase<T>::GetEmptyString( char8 )
{
0119B850 push ebp
0119B851 mov ebp,esp
0119B853 push ecx
0119B854 mov dword ptr [ebp-4],0CCCCCCCCh
const char8* address = sm_emptyString.m_Empty8;
0119B85B mov dword ptr [address],offset StringBase<char>::sm_emptyString (128F134h)
//const char8* address = &(sm_emptyString.m_Empty8[0]);
return address;
0119B862 mov eax,dword ptr [address]
//return sm_emptyString.m_Empty8;
}
我正在使用的内容: Windows 7,VC ++ 2008,Debug build
答案 0 :(得分:2)
使用功能?您需要的空字符串与StringBase<T>
及其状态或模板参数无关。
inline const char8* GetEmptyString( char8 )
{
static const char8 address[1] = {0};
return address;
}
编辑:为什么我建议使用像您的代码使用的联合是错误的。 C99标准说的一些事情:
与C ++相同,现在没有标准的方便。所以你不能使用union同时在同一个地方存储3个字符串。虽然我不确定究竟是什么导致了这些问题,但它可能完全在其他地方,你应该摆脱这些可疑的结构。