I know very little about COM, and searching Google for COM somhow did not find COM at all (probably because it searched .com address instead).
We are using a video capturing hardware. Its SDK allows us to register a callback when a frame is captured. An object interface is passed as a parameter to that callback, and we can get the large buffer address (to the captured frame pixels) and other information by querying to that object.
Now, it looks like calling Release() does not actually delete the memory but decreases the reference count, and when the count reaches 0, it is deleted, right? So, about that large buffer address mentioned above, how about "delete"ing the buffer using the "delete" keyword?
It seems that our program (not written by me, and the person who wrote the program quit the company) copies the pointer to the buffer into some class but never calls any Release() in the callback. Later, the buffer is "delete'd in the class. It seems Release()ing the frame interface object also deletes the buffer. But are they the same?
COM somehow counts the reference but what happens if user's code just deletes that memory? I am sorry if my question is obscure. In short, is it safe to delete a buffer that was gotten from a COM object.
Simplified code: Suspicious situation
void mycallback(IFrame f)
{
char* buffer;
f->GetBuffer(buffer);
MyClass m(buffer);
...
}
MyClass::DeleteBuffer()
{
delete m_buffer;
}
When the code copies the frame buffer content into its own buffer then nothing special happened. The frame buffer is still owned by the COM code, the code's own buffer is still owned by that code. Do not delete the COM buffer, that will invoke undefined behavior when the COM code deletes it too. You should only ever call Release() on a COM interface pointer if you called AddRef() first. In a scenario like this, the AddRef() call was made by the COM code before it invoked the callback. And the Release() call will be made after the callback returns.
Seeing a frame getting copied in a callback is quite normal, the frame buffer normally only stays valid for the duration of the callback. So you have to copy it if you use it later.
If you are chasing a memory leak then this is not likely the culprit. If there was a reference counting problem on the frame buffer then the program couldn't last for more than a minute before having consumed all available memory.
Try to use this place operator delete, CoTaskMemFree
Dealing with COM interfaces is more trickier :-)
Make sure you match the IUnknown::AddRef() and IUnknown::Release() calls
As long as you are in the same context, you can delete the buffer explicitly, even though you got them from a COM interface. But make sure you nullify the pointer after deletion, so that there is no post handling issues.
MyClass::DeleteBuffer()
{
if(m_buffer)
{
delete m_buffer;
m_buffer = null;
}
}
Related
I am using boost 1.55 (io_service doc). I need to call the destructor on my io_service to reset it after power is cycled on my serial device to get new data. The problem is that when the destructor is called twice (re-trying connection), I get a segmentation fault.
In header file
boost::asio::io_service io_service_port_1;
In function that closes connection
io_service_port_1.stop();
io_service_port_1.reset();
io_service_port_1.~io_service(); // how to check for NULL?
// do I need to re-construct it?
The following does not work:
if (io_service_port_1)
if (io_service_port_1 == NULL)
Thank you.
If you need manual control over when the object is created and destroyed, you should be wrapping it in a std::unique_ptr object.
std::unique_ptr<boost::asio::io_service> service_ptr =
std::make_unique<boost::asio::io_service>();
/*Do stuff until connection needs to be reset*/
service_ptr->stop();
//I don't know your specific use case, but the call to io_service's member function reset is probably unnecessary.
//service_ptr->reset();
service_ptr.reset();//"reset" is a member function of unique_ptr, will delete object.
/*For your later check*/
if(service_ptr) //returns true if a valid object exists in the pointer
if(!service_ptr) //returns true if no object is being pointed to.
Generally speaking, you should never directly call ~object_name();. Ever. Ever. Ever. There's several reasons why:
As a normal part of Stack Unwinding, this will get called anyways when the method returns.
deleteing a pointer will call it.
"Smart Pointers" (like std::unique_ptr and std::shared_ptr) will call it when they self-destruct.
Directly calling ~object_name(); should only ever be done in rare cases, usually involving Allocators, and even then, there are usually cleaner solutions.
I have MessagesViewer frame that I want to control the uniqueness of,
with this piece of code:
MessagesViewer* m_pMsgViewer = NULL;
void Application::ShowMessagesViewer()
{
if (m_pMsgViewer == NULL)
{
m_pMsgViewer = new MessagesViewer(
wxGetApp().GetContainer()->GetAppData()->GetMessages()
);
}
else
{
m_pMsgViewer->FillPage(wxGetApp().GetContainer()->GetAppData()->GetMessages());
m_pMsgViewer->SetFocus();
}
}
But when I call this for the first time, m_pMsgViewer starts to refer to valid data in the memory. When I close MessagesViewer frame, it destroys it automatically, but the pointer is still referencing to old address, and I can't control destroying the frame from this client code.
How can I dereference a pointer to destroyed frame?
#bogdan already proposed a good solution, but there is another, even more automatic one: store your frame pointer in wxWeakRef<> instead. I.e. keep exactly the same code as now but replace the declaration with
wxWeakRef<MessagesViewer> m_pMsgViewer;
The weak reference will be automagically reset to NULL when the window is destroyed.
One solution is to set m_pMsgViewer back to nullptr when MessagesViewer is closed. A safe way to do that is to add a handler for wxEVT_CLOSE_WINDOW to your frame. For example, add the following code to MessagesViewer's constructor:
Bind(wxEVT_CLOSE_WINDOW, [](wxCloseEvent& evt)
{
m_pMsgViewer = nullptr;
evt.Skip();
});
evt.Skip() lets the event propagate further to the default handler provided by wx.
This simple example assumes that m_pMsgViewer is a global variable. If it's actually contained within the Application object, you'll have to add some way to access it.
The obvious alternative of adding such code to MessagesViewer's destructor is not a very good idea, as the actual destruction of the MessagesViewer object is delayed according to the docs, so it would be theoretically possible for Application::ShowMessagesViewer() to call FillPage() on a frame that has been closed and marked for destruction but not actually destroyed yet.
Handling the close event resets the pointer early on, thus avoiding the problem above.
You need to mark somehow that MessagesViwer has been destroyed and cannot be referenced any more. This means some extra info in addition to m_pMsgViewer.
i am working on a issue where i see an intermittent crashes happening at the customer site, while code review, i found that we have written that some code in the destructor to free memory etc. but my question is when does this destruct-or gets called.
does it get called when the client call's Release on the interface. or how do we free resources consumed by an interface or when are we supposed to free those resources.
i know when the call to Relase returns "0" the COM calls the DllcanGetUnloadNow and it the dll is unloaded , what about freeing memory?
can anyone clarify
regards
tom
Typically the implementing object's destructor is called from Release if the reference count has reached zero. That is something that is performed by the implementing object's implementation of Release.
So, a typical implementation of Release looks like this:
IFACEMETHODIMP_(ULONG) Release()
{
ULONG cRef = InterlockedDecrement(&_cRef);
if (!cRef)
delete this;
return cRef;
}
Proper use of COM requires that certain laws about managing the object lifetime through reference counting.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms692481(v=vs.85).aspx
A single piece of code that does not follow this rule is sufficient to cause a crash.
Consumer of COM interface has no control over destruction of COM class/object. Consumer's responsibility is to accurately call IUnknown::Release once an interface pointer needs to be released. While returned zero is typically an indication of "last release, and destruction" of the object, this value is informational and does not guarantee object destruction. It is COM object responsibility to do proper freeing when there are no external references to the object exist.
The rest of destruction is the responsibility of COM object implementation. Once it detects it was released by everyone holding references, it typically does self-destruction, in simplest scenario. However, it does not have to be this way exactly. The object might have some background activity to extend lifetime, there are singletons and cached objects where there is certain logic to keep object alive etc.
Hence, troubleshooting destruction splits into proper interface reference counting (AddRef/Release) and checking COM server to properly shutdown activity in absence of consumers (including freeing memory and resources).
How to re-use correctly a TMemoryStream in a cycle. For example I have a timer and I'm downloading something from internet directly in a TMemoryStream object.
this object is declared as global variable:
TMemoryStream *ms;
then I use it in a timer function:
ms = new TMemoryStream;
.... other operations with ms ....
then I use it in other function where i do not need this stream at the end and want to empty it, and i do:
delete ms;
and then again is called same timer function, and it does the same cycle allocating and deallocating. It is correctly by this way ?
or I should ms->Clear() or ms->Free() in my last function where stream is no more need ?
I'm interested in how to reuse same global variable to read the stream (allocate) and empty the stream (deallocate).
Generally it is not dangerous or a mistake to instantiate and free an object in a timer, because timer calls have no overlap while thread calls may have. As Remy said, it is better to use only Clear() in timer and at end delete stream inside OnDestroy or form destructor (__fastcall ~TForm1()).
Free() is Delphi's equivilent to C++'s delete - the object gets destroyed. If you just want to reuse the same object but empty out its contents each time, use Clear(). Just remember that at some point, you will need to call delete to free the object when you are not going to use it anymore.
Yes, its actually "or". I shall explain. I am developing helper classes for myself, like DirectXToolKit. For managing COMs I`m using Microsoft::WRL::ComPtr<T> (wrl.h).
struct Renderer
{
ComPtr<ID3D11Device> m_Device;
ComPtr<ID3D11DeviceContext> m_ImmContext;
}
When all the resources are destroyed, the instance of the structure above should be destroyed as well, but after the dtor is called, I am triggering the error in Microsoft::WRL::ComPtr<T>, when it tries to release the device or context.
I have implemented the dtor where I manually release m_Device and m_ImmContext, but unfortunately the last member I try to release always encounters an issue in the function
unsigned long InternalRelease() throw()
{
unsigned long ref = 0;
T* temp = ptr_;
if (temp != nullptr)
{
ptr_ = nullptr;
ref = temp->Release();
}
return ref;
}
here
ref = temp->Release();
When I succeed releasing the device first, the context triggers the error, and vice versa (! yes, when one of them was successfully released, the destuction of the second member fails). There was already a question like mine (destroy directx device and swap chain), but the window and swapchain are already destroyed, like the other dx resources. Have no clue why is this happening. Any ideas?
Sorry for my imperfect English :3
I have fixed this issue. The problem was I have not understood std::shared_ptr good enough (the function std::make_shared actually (about shared pointers and their allocation)):
I have created the pointer like:
Obj *ObjPtr = new Obj();
and then just:
SomeOtherState.SharedObj = std::make_shared<Obj>(*ObjPtr);
and didn`t destroy the ObjPtr afterwards. The data ObjPtr was pointing on was still in memory, after SomeOtherState was destroyed (and as far as I have understood the issue should have gone as well if I have used the std::shared_ptr ctor) .
Most likely it was because of this memory leak, but there was another thing I have changed: CoUninitialize call was made before the last COM pointer was destroyed but from MSDN: CoUninitialize came that its important (from the first para actually):
Closes the COM library on the current thread, unloads all DLLs loaded by the thread, frees any other resources that the thread maintains, and forces all RPC connections on the thread to close.
So I have replaced CoInitialize and CoUninitialize correspondently and the issue have gone. If someone had had the same troubles, this could somewhat be a solution (either or both the first and the second change I have made).
I should probably add "com" tags for my question
the problem MAY be somewhere when you obtain the ImmediateContext.
According to the documentation:
http://msdn.microsoft.com/en-us/library/windows/desktop/ff476529%28v=vs.85%29.aspx
The GetImmediateContext method increments the reference count of the immediate
context by one. Therefore, you must call Release on the returned interface pointer
when you are done with it to avoid a memory leak.
So I >>>guess<<< that you've forgot releasing the context somewhere so the Device release fails afterwards.
BTW: Make also sure that resources are ALWAYS released in reverse order.