0

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 *.

4 Answers 4

1

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

pRend->cp = cpRT;

should be replaced with

cpRT->QueryInterface(&pRend->cp);
Sign up to request clarification or add additional context in comments.

3 Comments

Don't you need to pass an IID to QueryInterface()? Also, what is the benefit of calling QueryInterface() in this situation? Is it that it increments the interface's reference count? If you already have the right interface pointer, why not call AddRef() instead?
In COM terminology, you should not assign anything directly. It should be done using QI. If you are using smart pointers(CComQIPtr) then you can assign directly.
If you already have the right interface pointer, then yes -- you probably should call AddRef() rather than QI() again.
0

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();
  }
};

Comments

0

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?

2 Comments

Yes. var doesn't point anywhere until you assign it a target, either on the heap (from malloc) or another variable (var = &data_var). If you just use it immediately, it will overwrite some random bit of memory depending on what leftover value was in it, and may crash (or fail more subtly).
Don't use malloc. Use new on your struct. This way when you call delete (not free) the smart pointer's destructor will be called.
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.