Memset on objects will result in crash? Then none of your MFC apps will work.

25 03 2008

Icon Description
While stepping from C to the C++ world, it’s the first pitfall that we encounter – initializing an object with memset. Since memset if faster, we used to initialize objects like this,

CObject obj;
memset( &obj, 0, sizeof(obj));

More than enough for a crash! Because if the class contains virtual functions, then the first 4 bytes holds the pointer to vtable. If we use memset, then the vtable pointer will be overwritten to 0 and it may end up in crash.

But, do you know one thing? The famous MFC framework uses memset to initialize some of its objects such as CDialog, CScrollView etc. Can’t believe? It does, but safely. Without damaging the vtable pointer.

icon_underthehood.jpg
If you check the constructor of CDialog, you can see one macro – AFX_ZERO_INIT_OBJECT();. This macro calls memset internally. See the implementation of macro below.

// zero fill everything after the vtbl pointer
#define AFX_ZERO_INIT_OBJECT(base_class) \
memset(((base_class*)this)+1, 0, sizeof(*this) - sizeof(class base_class));

But it’s safe. Because it skips the vtable ptr.

Icon Note
Don’t try this macro in your source. Because CDialog doesn’t contain any objects as members. It contains just some pointers and handles. If your object contain some class variables as members which contain virtual table, then that vtable ptr may be overwritten. Take care!

Advertisements




Trigraph char sequences in C & C++

25 03 2008

Icon Description
There are some triplet character sequences present in C & C++ to represent some special punctuation characters. The trigraph sequences are used for compatibility of source code written in ISO 646 or EBCDIC charset.

icon_underthehood.jpg
// Is this a valid statement? I can’t believe. But for compiler is valid.
??=define arraycheck(a,b) a??(b??) ??!??! b??(a??)

But when we apply trigraph sequence, the above code block became as follows.
// Wow!!! It’s a valid one…
#define arraycheck(a,b) a[b] || b[a]

Please see list of trigraph sequences below.
Trigraph Punctuation Character

??=	            #
??(                 [
??/                 \
??)                 ]
??’	            ^
??<                 {
??! 	            |
??>	            }
??- 	            ~

And one trigraph pitfall.
// Whether the following line compiles ???????/
cout << “Whether you can see this message?”;

Find your answer and take care trigraphs next time…
Thanks to Wiki for examples and the list.





Watch heap objects eventhough the symbol went out of scope.

25 03 2008

Icon Description
While debugging we want to watch some objects through out. An object can be watched only with its symbol and it should be valid in the current stack frame. For instance,

CJobManager* CJobManager::GetJobManager
{
    return m_pJobManager;
}

For watching the JobManager instance, we need the symbol m_JobManager in this stack frame. When the function leaves, we can’t see the JobManager instance anymore. So how can i watch these heap objects without the symbol in stack frame?

Icon How Can I Do It?
1) Get the address of your heap object. Just add to watch window and get the location. For instance assume its 0x00034de0.
2) Now add a new entry to the watch window like this – (CJobManager*)(0x00034de0)
3) Now eventhough your function returns and you loss the symbol, still you can see your heap object.

Really helpful isn’t it? i was fed up with the global objects in my project and atlast find this method to watch them premenently.