c++ – Storing a COM pointer in a struct – Education Career Blog

My program is crashing every time I try to store a COM pointer into a struct, and then later try to use the original pointer. I don’t have debug access to tell exactly what’s wrong.

pRend->cp = cpRT;

ID2D1SolidColorBrush *scBrush;
ERF(cpRT->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::CornflowerBlue), &scBrush));

It crashes on CreateSolidColorBrush. However, if I comment out pRend->cp = cpRT, it doesn’t.
By the way, pRend->cp and cpRT are of type ID2D1HwndRenderTarget *.

,

Instead of assigning directly QI and then store i.e.,

pRend->cp = cpRT;

should be replaced with

cpRT->QueryInterface(&pRend->cp);

,

It’s unclear how much code exists between when you assign it into the struct and later use it in CreateSolidColorBrush. If it’s a non-trivial amount of time, it’s possible that you have a reference counting issue.

Are you storing a raw pointer in the struct? If so, switch it to a CComPtr and see if the crash goes away.

For instance. If you had the following type definition for the value of pRend (call it Render) and the value pRend was destroyed before making the CreateSolidColorBrush call, you could see this behavior.

struct Render { 
  ID2D1HwndRenderTarget *pCt;
  ~Render() {
    pCt->Release();
  }
};

,

As it turns out, I managed to stop the crashing by allocating pRend with malloc. This is not a problem because I will call free when I don’t need it anymore. I’m interested in why calling malloc fixes this though. I’m used to just doing Datatype * var; and then just using var. Is that bad?

,

It’s a smart pointer. I’m guessing you’re inadvertantly calling release on it. In particular, it’s addressof operator (unary op&) is overriden to call Release().

See what happens if you instead assign it to a reference, an ID2D1HwndRenderTarget*&.

Obviously, if you assign to a reference, you won’t be able to reseat it.

Leave a Comment