Do not delete [] a scalar pointer !!!

Recently I got tangled into this problem in my code - Calling a vector dtor for a scalar pointer. We all know that it is perfectly illegal to do that. For example, if we allocate something like this:-

OurClass *p = new OurClass();

and try to delete like this:-
delete []p;

then we are going to end up in trouble. Ofcourse we know that we will end up in trouble. But I have really not given a thought HOW ?

When we allocate an array of items eg. OurClass pa[] = new[5] pa(), the compiler actually allocates the necessary amount of memory, calls the ctors for each allocated class and also prefixes the block of memory of the 'n' items allocated with the number of items allocated.

NumItems | OurClassObject1 | OurClassObject2 | ...... | OurClassObjectn

But pa always points to the first item in the allocation, thereby the item count prefix remains hidden. When we call delete[] pa, the compiler uses the item count prefix to delete the allocated objects and call the dtors.

Now i think i don't need explain any further as what happens when i use delete []p, and what junk value will the compiler take from the memory location just before the memory location p believing it to be the item count.

I learnt this interesting information from OldNewThing Blog. Adam Nathan has explained it well with the compiler generated assembly and a bit of excellent code for the dtor.

And what if we do a scalar delete on a vector pointer, there is less harm, you do not unallocate the memory completely, you leave behind remnants of your allocated memory which you cannot reclaim.

Either way, it is better to be disciplined while programming.

Where do you QueryInterface ???

For an ATL class, the QueryInterface is implemented in CComObject. The figure below is the inheritance hierarchy for a class generated by the wizard representing an ATL-COM object.

CComObjectRootBase has an InternalQueryInterface method, which uses the interface map built by the BEGIN_COM_MAP macro to resolve IID -> interface pointer. The BEGIN_COM_MAP macro also defines a method _InternalQueryInterface, which passes the map on to InternalQueryInterface. CComObject implements QueryInterface, and calls _InternalQueryInterface.

NOTE:
CComObjectRootEx: Provides methods to handle object reference count management for both nonaggregated and aggregated objects.


CComObject: Implements IUnknown for a nonaggregated object. It is a template class that takes a class like CSomeClass derived from CComObjectRootEx.


CComObjectNoLock: Implements IUnknown for a nonaggregated object, but does not increment the module lock count in the constructor. ATL uses CComObjectNoLock internally for class factories.

CComCoClass: Defines the object's default class factory and aggregation model.

Use Of Class Factories !!!

To understand quickly and to explain in the simplest way, Class Factories are the factory classes that create a COM object. A class factory may be responsible for creating one or more COM objects. In the case of COM OutOfProc servers, the server registers the class factories for objects that it can create in a system-global table using CoRegisterClassObject. Whenever a client does CoGetClassObject for a CLSID, the COM run-time can look it up in the system global table, and return the factory instance. The case with InProc servers is also similar but through the DLLGetClassObject.

The point here is that class factories are required [irrespective of how they exist physically in the servers, either as seperate instances or the COM object itself behaving as a factory for the objects of that type], they abstract the creation of the COM object through IClassfactory::CreateInstance.

Unsafe Operations with STL !!!

It is UNSAFE to do any operation on an STL container that will modify its size while holding a reference to one of its exisiting element. What could happen is, when you do an operation, say push_back on a vector, it determines if there is enough space available to add a new element. If there is not sufficient space available, it allocates new space for whole of the data structure and deletes the old buffer. At this point, any reference to one of its elements created prior to push_back would have gotten corrupted.

For example, the following usage of code is dangerous when used within a single scope.

SomeClass &sc = m_Vector.back();
m_Vector.push_back(someotherobject);
.
.
.
sc.SomeMethodCall(); // Code might crash here.

Consoles for Mr.GUI !!!

Learnt something new, a small one but very useful.
Many times I have seen GUI applications accompanied by console windows that show logs or trace information of the application. How do we do that for our application ?

Any GUI application can create its own console window just by calling AllocConsole Win32 API. Actually any process can use that API to allocate a new console. And the application must also learn to be disciplined enough to FreeConsole. Ok, fine. I used that in my small MFC application and was happy to see the console. But I did not see anything displayed on the console. As we know, each process has its own stdin, stdout and stderr. So redirect the console output of your parent application to the console. How do you do that ?

Use the FILE *freopen(const char *path, const char *mode, FILE *stream); API. The freopen function closes the file currently associated with stream and reassigns stream to the file specified by path. By that way, call freopen as follows:-

FILE *fpStdOut = freopen ("CONOUT$", "w", stdout);

This means that I want to reassign the standard console output stdout with the console output of the parent application CONONUT$. So any printf calls will print the characters on the console. Cool !!!

Setting Environment Variables !!!

Need to change or set the value of an environment variable programmatically and without the need to restart/log off the machine. I need the change to reflect for all processes, ie, I need to change the global environment value and not the one in the PEB [Process Environment Block] of a process. Frustated with setting the value of an environment variable !!!

For getting the set of environment variables or to get the value of an environment vaible from your C# program, there is the GetEnvironmentVariables/GetEnvironmentVariable API in the System.Environment class. But there is no API for setting the value of an environment variable.

The system environment variables are stored in the registry under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment.

The [current] user environment variables are stored in the registry under HKEY_CURRENT_USERE\Environment.

When the system boots up, the environment is built from this list in the registry. If we change the value directly in the registry, the change does not effect. For example, change the value of TEMP variable that specifies the temporary files directory, in the registry and check with the set command in the command prompt, you won't see the change you made. Or just create a new entry in the registry under the one of the above mentioned registry paths, you won't see the change. Also you can verify that programmatically with GetEnvironmentVariable API.

But the changes you made will be reflected after a log off or restart. After some research, I found the Win32 SDK API SetEnvironmentVariable. But unfortunately, it just the changes the variable value in the PEB of that process alone, it does not effect the global environment values. Pathetic.

There is definitely a solution for this simple and primary problem. All we have to do is to update the registry as we discussed before, and also notify that the global enviroment variable list has been modified. Ok, how do we do that ?

Simple, one line of code.

// Broadcast the WM_SETTINGCHANGE message for Enviroment

SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0,
(LPARAM) "Environment",
SMTO_ABORTIFHUNG,
5000, &dwReturnValue);

Of course, this is C++ code. Not a big deal to do that in C# or whatever.

CoMarshal.... working in NT, Not working in XP !!!

Problem:-

I have created a multi-threaded application which works without any problems on a NT-4.0 Workstation/Server. When I try to run the same application in Windows XP, I get an error in a call to CoMarshalInterThreadInterfaceInStream which returns -2147418113.
I have provided a snippet of the code below where the call fails in Windows XP.
Environment - Windows-XP,SP-2,Visual Studio 6.0,SP-4,ATL-3.0
Should I be doing anything different in Windows XP?

HRESULT hr = S_OK;
IUnknown** pp = p->m_vec.begin();
while (pp <>m_vec.end() && hr == S_OK)
{
if (*pp != NULL)
{
IEvent* pEvent = (IEvent*)*pp;
IStream* pIStream;
HRESULT hr = CoMarshalInterThreadInterfaceInStream(IID_IEvent, pEvent, &pIStream);
if(SUCCEEDED(hr))
{
CComPtr pMarshalEvent;
hr = CoGetInterfaceAndReleaseStream(pIStream, IID_IEvent, (void**)&pMarshalEvent);

if(SUCCEEDED(hr))
hr = pMarshalEvent->NewCurrentCassette(m_pCurrentCassette, m_setBy);
}
P++;
}

Thread 2:-

I remember facing this problem long time back.The reason it happened was b'cos of the Free-Threaded marshaller code in Finalconstruct and FinalRelease even though i don't remember the logic behind it.In my case commenting the Free-Threaded marshaller code did the trick.

1) The commented code in FinalConstruct was
hr = CoCreateFreeThreadedMarshaler( GetControllingUnknown(), &m_pUnkMarshaler.p);
PROCESS_HR(IID_ISomeThing);

2)In FinalRelease it was the corresponding m_pUnkMarshaler.Release(); that was commented.

3)In the header,DECLARE_GET_CONTROLLING_UNKNOWN() and COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pUnkMarshaler.p) and CComPtr m_pUnkMarshaler; was commented.

4)Remove marshalling code i.e,CoInterface and related marshalling code.The interface pointer can be accessed in the secondary thread directly,no need of marshalling.

I remember faintly that Free-Threaded marshaller is basically to optimize marshalling.So in my case removing it did not have any side-effects as we were not worried about Free-Threaded marshaller.Again the above fix might work but the best thing to do will be to anaylze the apartment link(STA,MTA etc.) between say the client and the component and then come to a conclusion.

Thread 3:-

You need not marshal/unmarshal to call a method on the interface pointer since the sink class itself deriving from the IConnectionPointImpl takes care of unmarshalling. You can see the code in your connection point implementation class.

Thread 4:-

I don't think IConnectionPointImpl class as such has anything to do with marshalling, it is the m_pUnkMarshaler member object.It is the call to CoCreateFreeThreadedMarshaler in FinalConstruct that initializes the m_pUnkMarshaler object.I suggest reading the documentation about CoCreateFreeThreadedMarshaler in order to come to a conclusion whether to use it or not.By default ATL provides the code calling CoCreateFreeThreadedMarshaler API to do efficient marshalling across *thread of the same process(Refer doc)*, but depending on our need we may or may not use it.In my case we did not need it so we commented it out.It depends on the need,but generally i think it is safe to comment it out if we are going to access interface pointers in secondary threads.Hope this helps.

Consts in .NET !!!

I was doing some programming with C# and I had to use some 'const's as everybody does generally in programming. I had a class that simply had const string variables for my DB table names and stuff like that. My program was not working well and I started debugging and in the debugger, I was shocked to see that the const variables did not show the string values I had assigned. I did rebuilt and other non-sensical stuff like that until I learnt this about the consts in .NET:- 'const' variables in .NET do not exist as variables out of the assembly they exist in. Instead, during compilation, they get embedded [hard-coded] where ever you use them, and so when you debug, you do not see the proper value that you had assigned. For debugging purposes you have to output diagnostic trace messages and verify.