I cannot replicate this problem in a smaller program that I can show so I will illustrate the question with screenshots.
I have a class that declares a union and a static member of the 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 };
I then have a function that returns the address of the string. For debugging purposes, I have added the variable address
so that I can add it to the watch window. Here is the function (T
here is a char8
where char8
is a typedef for char
):
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;
}
As you can see, initially I had the one return statement, which I commented out so that I can debug the snippet. The other line that is commented out is taking the address of the first (and only) element of the array; this commented out line does the same thing as the line previous to it, which is: const char8* address = sm_emptyString.m_Empty8;
.
The program crashes because I am not getting the correct address by the above function and this has stumped me. Below I will start screenshots of my debugging session:
Above, you can see that I am breaking just before the address is copied to the pointer. Below is the watch window values for sm_emptyString
and address
at this break.
So far, nothing special. Below is the screenshot after stepping over one line of code.
And the corresponding watch window:
As you can see, the value copied to address
is wrong. Another thing to note is that this function gets called a few times and the copy of the static variable address to address
is correct. When the address is incorrect and is returned by the function, my program crashes (because of the assumptions about the address later on in the program).
What is happening here? Am I over-writing memory somewhere? How do I go about debugging this?
EDIT:
The disassembly (according to the debugger, the address of sm_emptyString
is 129F184
, different than what the disassembly shows which is 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;
}
What I am using: Windows 7, VC++ 2008, Debug build
Use a function? The empty string you need has nothing to do with StringBase<T>
nor its state nor its template argument.
inline const char8* GetEmptyString( char8 )
{
static const char8 address[1] = {0};
return address;
}
EDIT: Why i suggest it is that using union like your code uses is wrong. Some things that C99 standard say:
Same goes with C++, just don't have the standard handy now. So you can not use union to store 3 strings at same place at same time. While I am not sure what actually causes the problems, it is likely totally elsewhere, you should get rid of such questionable constructs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With