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.
Related
I am working on a simple idea and I came across this problem. What happens if after an async call as shown below the program exits without calling shared_future.get()?
Will I have a memory leak?
//async function
std::shared_future<double*> sharedFutures = std::async(std::launch::async, myAsyncFunc, argument1, argument2);
if ( realtimeCondition )
{
//what happens to sharedFutures memory allocation after exiting
//memory leak?
return 0;
}
//getting results
for (sharedFuture : sharedFutures )
double* res = sharedFuture.get();
return 0;
shared_future to some extend mimics std::shared_ptr. They both manage a shared resource. The resource is released when the last shared_x is destroyed. This is checked in the destructor (cppreference: https://en.cppreference.com/w/cpp/thread/shared_future/%7Eshared_future):
~shared_future(); (since C++11)
If *this is the last object referring to the shared state, destroys the shared state. Otherwise does nothing.
If a class manages a resource it should release it in the destructor. Thats true for all classes. The difference here is that the same resource is shared between potentially many objects. So each object has to check if it is the last one to own the resource before it can destroy it.
hence, shared_future destructors are called when exiting and not when having collected the futures via get()?
It would be bad and weird if an object suddenly destroys itself when you call one of its methods. Here specifically, both shared_future and shared_ptr would be practically useless when everytime you access the object they manage that object gets destroyed. The shared_future in your example gets destroyed when it goes out of scope.
If I understand your question correctly calling get() on future will change state->retrieved of future to true but not calls destruction. Destruction of future of any type doesn't depend on its own state.
I have this chunk of code...
A non-static member method (serving as callable for thread):
void Object::unregister()
{
...
}
and destructor like this:
Object::~Object()
{
std::thread cleanup(&Object::unregister, this);
cleanup.detach();
}
What I see as a problem is that I am running a thread with parameter this which become invalidated when destructor finishes, so I assume it is dangerous, because I do not have any garantee, that the cleanup thread already started - and this my subquestion - is safe if this would be invalidated (destructor finishes) before the call to unregister finishes completely (in other words is it ok, if it already started, but did not finish completely)?
I would say that answer is No as the copy of this pointer is used with callable, but I am not sure as the app behaves, like it does not mind and everything is OK.
If it is ok that thread just started and did not finish yet, is there any way to know that the thread is already running? Would usage of call to joinable() return me true just when the thread is already executing or it can return true before the thread's execution started?
Is there any way how to do it safe and be sure that callable &Object::unregister and this will not be invalidated, because Object was destroyed meanwhile?
is safe if this would be invalidated (destructor finishes) before the call to unregister finishes completely (in other words is it ok, if it already started, but did not finish completely)?
No, it's not safe.
Consider the following C code:
void Object_unregister(void* obj)
{
Object* this = (Object*)obj;
fclose(this->file_handle);
while (this->ref_counter > 0) {
fclose(this->ref_array[this->ref_counter]->handle);
free(this->ref_array[this->ref_counter]);
this->ref_array[this->ref_counter] = NULL;
--this->ref_counter;
}
}
void destroy_Object(Object** this)
{
pthread_t thread;
pthread_create(&thread, NULL, &Object_unregister, (void*)*this);
pthread_detach(&thread);
free(*this);
*this = NULL;
}
This is, at a very basic level, what your C++ code is doing. In this code, we create the thread, then detach it, then immediately free the memory space where the Object was at. In this way, there's no guarantee that the this pointer in the Object_unregister function will point to the same Object that was passed to it.
There is a (general) guarantee that the thread function will still point to the same function pointer address the thread was created with, and that it will run until that function has completed, and in the above code, there is a guarantee that the this pointer will point to the same memory address from when the function was called.
But ...
this could point to 0xABADCAFE and this->file_handle will point to this + sizeof(Object::file_handle), but if you've deleted the object, then what is actually at that address could no longer point to a valid reference of an Object type.
It could point to some random bit of encryption code, or a new function, or just about anything, but it could still point to the object that was originally there if that memory space was not reallocated by the kernel.
So no, it's not safe.
Is there any way how to do it safe and be sure that callable &Object::unregister and this will not be invalidated, because Object was destroyed meanwhile?
Well it depends on what your Object::unregister code actually does in the context of the rest of your code. It's not immediately clear why you want to thread the destructor and you don't just call this->unregister(); in the destructor, example:
Object::~Object()
{
this->unregister();
}
That's as safe as you can get in the context of your code.
But if there's other things that necessarily need to be done in a threaded way, you could do many architectural things to thread the destruction of the object, from static values to locking mechanisms, but essentially what you would need to do is make copies of the specific values you need to unregister so they remain valid in your thread code.
When my objects are destroyed, I keep getting an Assertion failure in
dbgheap.c line 1399
_ASSERTE(pHead->nBlockUse == nBlockUse);
I can't find any reason why this happens. The pointers are properly initialized to NULL in the constructor:
CPlayThread()
{
m_pPlayer[0]= NULL;
m_pPlayer[1]= NULL;
};
This is the code that actually creates the objects.
if(pParam->m_pPlayer[0] == NULL) //pParam is a CPlayThread*
{
if(config.m_nPlayerMode == modeSocket)
pParam->m_pPlayer[0]= new CSocketPlayer();
}
The objects get destroyed when the thread is destroyed, and this is where the assertion occurs.
~CPlayThread()
{
if(m_pPlayer[0])
delete m_pPlayer[0];
m_pPlayer[0]=NULL;
if(m_pPlayer[1])
delete m_pPlayer[1];
m_pPlayer[1]= NULL;
};
I'm at a total loss here. It used to work fine and somehow it started crashing at a client's location after three or four days of running continously. At the same time my debug executable started asserting every
single time a player was destroyed. There are up to 96 threads that might be playing at any given time (with two players each thread, alternating - the players were created and destroyed as needed). So after looking for a solution and not finding one, I decided to just keep the objects for the duration of the application exectution. So now I only get the assertion when I close the debug version of the program (and presummably there is an unnoticeable crash on closing the release version, which is never because this should run 24/7).
I just need to know what I am doing wrong. Any help would be appretiated.
What type is m_pPlayer[0] ( Like David asked. ) is it a base type of CSocketPlayer or is it CSocketPlayer itself. ? If it's a base type you need to make the destructor in the base class virtual. That might be related to your problem. If not, then the problem must be that you already deleted the object. This can be due to a racing condition, where 2 threads run the destructor with the same pointers.
What also could be is that either the new or delete operator is overloaded, for example allocating from another heap. Guess that is far fetched .... but possible ..
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 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;
}
}