See the question and my original answer on StackOverflow

It ultimately depends on how the start pointer and the function are written, but in general, with ATL pointers and functions coded as they should be:

In debug mode:

CComPtr<ISomeComObj> mycomobj;
SomeOtherComObject1->FunctionToFindComObject(&mycomobj);
SomeOtherComObject2->FunctionToFindComObject(&mycomobj); // will throw an ATL assert

Extract from atlcomcli.h:

...
//The assert on operator& usually indicates a bug.  If this is really
//what is needed, however, take the address of the p member explicitly.
T** operator&() throw()
{
    ATLASSERT(p==NULL);
    return &p;
}
...

In release, you'll have a problem. So what you should do is this:

CComPtr<ISomeComObj> mycomobj;
SomeOtherComObject1->FunctionToFindComObject(&mycomobj);
mycomobj.Release();
SomeOtherComObject2->FunctionToFindComObject(&mycomobj);

Note it's good to know CComPtr::Release() can be called safely (in debug and release mode) even if the contained pointer is null, so this works fine for example:

CComPtr<ISomeComObj> mycomobj;
mycomobj.Release();

PS: my advice is always use debug mode to develop.