I have a problem freeing up memory of an object.Here is my code:
void Gateway::connect(DWORD dwIP)
{
if (m_objRRSInterface != NULL)
{
//delete m_obj;
m_obj = NULL;
}
m_obj = new objClass();
m_obj->SetCallBackFn(fncp);
if (m_obj->OpenSocket(dwIP, 3002))//3002 -port number
{
m_bConnect = TRUE;
}
else
{
m_bConnect = FALSE;
delete m_objRRSInterface;
m_obj = NULL;
}
}
objClass is not my own class , it is imported from an external .dll.
OpenSocket method opens a socket connection on port 3002 and then I get all the data on fncp.
This function work's OK for the first time that i call it.
The problem appears when I call the function the second time.The problem that I have is that there is no CloseSocket method that i could call to reliable close the socket.
My question to you guys is that :Is there any method to dispose of an object and all this object dependences?
I've tried calling delete m_obj; but this hangs the application.
You should investigate about C++ destructors, which are meant to do what you are after.
This is where resources clean-up is usually done, but this is up to the programmer of the class. In other words, it is likely that objClass destructor does it resources clean-up there, but without reading the docs or the code, I cannot say.
The fact that your application hangs has nothing to do with C++ or destructors in themselves, anyway. Rather, it seems a question of the way you use your DLL, like calling delete at the wrong time, or before some manual clean-up.
But without knowing about objClass interface and semantics, I cannot help with this.
If there is no function to explicitly clean up the object or close the socket in the library documentation, does it automatically shut down the socket if there is no activity after a certain amount of time?
If you have a way of telling if the socket is still open, you could pass the object to a helper thread to delete it when it detects that the socket is closed.
The only other thing that I can think of is that it may be possible to reuse the object for the new connection.
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 come from Java so this is pretty hard for me to understand.. I am writing a client/server program to start learning C++.
ServerSocket server(30000);
while (true) {
ServerSocket new_sock;
server.accept(new_sock);
std::cout << "client connected...\n";
ClientConnectionThread *cct = new ClientConnectionThread(new_sock);
cct->start();
}
My problem occurs when I try to write to the socket in the ClientConnectionThread.
client_sock << someObj;
Exception was caught in cct: Could not write to socket.
My assumption is that after the cc->start(); command the ServerSocket will lose 'scope' and be popped off the stack and automatically closed. To fix this I changed the code to:
ServerSocket server(30000);
while (true) {
ServerSocket *new_sock; <----
server.accept(new_sock);
std::cout << "client connected...\n";
ClientConnectionThread *cct = new ClientConnectionThread(new_sock);
cct->start();
}
But the program didn't even enter the loop.. with no error messages telling me why that didn't work (Of course changing the necessary code to accept the pointer).
If it is not obvious what I am trying to do.. I am looking to create a new thread on every client connection to handle each client. Of course the thread will need a reference to the socket to receive and send on - which is why I pass it to the CCT object.
If you need more code let me know.
Your first code does not work exactly because of what you said. The object is allocated on the stack but once it leaves of scope, it is destroyed and the underlying pointer to the socket is closed as a consequence.
If you want to keep the object "alive", you need to use pointers. You got that right, but missed a important point: you the to allocate the object! To do so, you need to use the operator new as the following:
ServerSocket *new_sock = new ServerSocket;
Now here's the catch, on Java your object gets deallocated automatically by GC, but C++ has no garbage collector, so you need to do it by hand. Once you are done using the object, you need to delete it.
delete new_sock;
This can be a lot tricky, can cause a lot of crashes and even memory leaks. If you wish some behaviour more like Java's GC, you can use a shared_ptr, that will automatically deallocate the object (it's not that simple, but you will easily find more about that on Google.)
std::shared_ptr<ServerSocket> new_sock = std::shared_ptr<ServerSocket>(new ServerSocket);
server.accept(*new_sock);
(assuming you are compiling against C++11)
You could make your first version work if you pass a copy instead of a reference of the ServerSocket to your thread (if that is possible - server socket would need a proper copy constructor for this). The original ServerSocket would go out of scope as you pointed out, which is now no longer a problem, as the copy is still valid.
If this is not an option for you go with the version Rogiel pointed out (and stick to resource handles like unique and shared pointer, those make your life a lot easier if you are used to GC :-) ).
I'm maintaining an application which uses Windows Explorer overlay icons. Occasionally some operations require me to forcibly refresh explorers view for a particular folder. I do so using the following function which uses COM:
void RefreshExplorerView(CString strPath)
{
CComPtr<IShellWindows> pShellWindows;
CoInitialize(NULL);
if(SUCCEEDED(pShellWindows.CoCreateInstance(CLSID_ShellWindows)))
{
IDispatch* pFolder=NULL;
VARIANT variant;
V_VT(&variant) = VT_I4;
for(V_I4(&variant) = 0; pShellWindows->Item(variant, &pFolder) == S_OK; V_I4(&variant)++)
{
CComPtr<IWebBrowserApp> pWebBrowserApp;
if(SUCCEEDED(pFolder->QueryInterface(IID_PPV_ARGS(&pWebBrowserApp))))
{
BSTR LocationURL = NULL;
pWebBrowserApp->get_LocationURL(&LocationURL);
if(LocationURL != NULL && strPath.CompareNoCase(LocationURL) == 0)
{
CComPtr<IServiceProvider> pServiceProvider;
if(SUCCEEDED(pWebBrowserApp->QueryInterface(IID_PPV_ARGS(&pServiceProvider))))
{
CComPtr<IShellBrowser> pShellBrowser;
if(SUCCEEDED(pServiceProvider->QueryInterface(IID_PPV_ARGS(&pShellBrowser))))
{
IShellView* pShellView;
if(SUCCEEDED(pShellBrowser->QueryActiveShellView(&pShellView)))
{
pShellView->Refresh();
pShellView->Release();
}
}
}
}
SysFreeString(LocationURL);
}
pFolder->Release();
pFolder = NULL;
}
}
CoUninitialize();
}
I've noticed that when my program does this refresh regularly it slowly grows in size and UMDH has shown me that I appear to be leaking pFolder and pShellWindow instances every time this runs. I can't work out why on earth this happens since as far as I can tell these are released properly. Can anyone see what I'm missing?
You release pShellWindows after CoUninitialize, which is incorrect.
The rest of interfaces seem to be released fine. Note that you could improve cleanless and readability greatly by using CComQIPtr instead of QueryInterface, and not using raw pointers at all (BSTR, IFoo*) and replace them with smart auto-releasing wrappers.
pFolder might be leaking too, if Item call is successful but returns code other than S_OK. Again, use of CComPtr<IFolder> instead of IFolder* would immediately resolve this problem without even drawing any attention to it.
CoInitialize(NULL);
There's more than one problem with this statement. #Roman explained how you can leak by uninitializing too soon. But this will also go bad in more than one way, the apartment state of a thread is a Really Big Deal in COM:
You are not checking the return value of CoInitialize(). This will blow up the client app that calls this function if it has already called CoInitializeEx() and selected MTA instead of STA. That will make CoInitialize() fail, you cannot change the thread state after it was committed. Your CoUninitialize() call will blow the client app to smithereens, making all of its subsequent COM calls fail.
Selecting STA also requires that you implement the contract for a single threaded apartment. Which states that you never block the thread, you're okay with that. And that you pump a message loop. The message loop is crucial to marshaling calls to the single-threaded apartment. You are not okay with that, nor can you reasonably ensure that this is taken care of in a function like this. Particularly important for the shell interfaces, the vast majority of them are not thread-safe. The consequence of not pumping is deadlock. You may get away with not pumping, it is not a guaranteed deadlock. You'll get a bit of leeway here since these are probably out-of-process interfaces.
Particularly the last requirement can only be met by the code that created the thread that calls this function, only it is in control over what the thread does beyond calling your function. If you cannot get the guarantee that the client app initializes COM correctly then the only truly safe thing to do is to create a thread yourself.
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.
I have a destructor that performs some necessary cleanup (it kills processes). It needs to run even when SIGINT is sent to the program. My code currently looks like:
typedef boost::shared_ptr<PidManager> PidManagerPtr
void PidManager::handler(int sig)
{
std::cout << "Caught SIGINT\n";
instance_.~PidManagerPtr(); //PidManager is a singleton
exit(1);
}
//handler registered in the PidManager constructor
This works, but there seem to be numerous warnings against explicitly calling a destructor. Is this the right thing to do in this situation, or is there a "more correct" way to do it?
If that object is a singleton, you don't need to use a shared-pointer. (There's only one!)
If you switch it to auto_ptr you can call release() on it. Or perhaps scoped_ptr, calling reset().
This all said, I'm 99% certain that exit() will destruct statically constructed objects. (Which singletons tend to be.) What I do know is that exit() calls the registered atexit() functions.
If your singleton is not destructed automatically by exit, the proper thing to do in your case is to make an atexit hook:
void release_singleton(void)
{
//instance_.release();
instance_.reset();
}
// in main, probably
atexit(release_singleton);
Never explicitly call destructor unless object was constructed with placement new.
Move cleanup code into separate function and call it instead. The same function is to be called from the destructor.
Turns out that doing this was a very bad idea. The amount of weird stuff going on is tremendous.
What was happening
The shared_ptr had a use_count of two going into the handler. One reference was in PidManager itself, the other was in the client of PidManager. Calling the destructor of the shared_ptr (~PidManager() ) reduced the use_count by one. Then, as GMan hinted at, when exit() was called, the destructor for the statically initialized PidManagerPtr instance_ was called, reducing the use_count to 0 and causing the PidManager destructor to be called. Obviously, if PidManager had more than one client, the use_count would not have dropped to 0, and this wouldn't have worked at all.
This also gives some hints as to why calling instance_.reset() didn't work. The call does indeed reduce the reference count by 1. But the remaining reference is the shared_ptr in the client of PidManager. That shared_ptr is an automatic variable, so its destructor is not called at exit(). The instance_ destructor is called, but since it was reset(), it no longer points to the PidManager instance.
The Solution
I completely abandoned the use of shared_ptrs and decided to go with the Meyers Singleton instead. Now my code looks like this:
void handler(int sig)
{
exit(1);
}
typedef PidManager * PidManagerPtr
PidManagerPtr PidManager::instance()
{
static PidManager instance_;
static bool handler_registered = false;
if(!handler_registered)
{
signal(SIGINT,handler);
handler_registered = true;
}
return &instance_;
}
Explicitly calling exit allows the destructor of the statically initialized PidManager instance_ to run, so no other clean up code need be placed in the handler. This neatly avoids any issues with the handler being called while PidManager is in an inconsistent state.
You really don't want to do much of anything in a signal handler. The safest the thing to do is just set a flag (e.g. a global volatile bool), and then have your program's regular event loop check that flag every so often, and if it has become true, call the cleanup/shutdown routine from there.
Because the signal handler runs asynchronously with the rest of the application, doing much more than that from inside the signal handler is unsafe -- whatever data you might want to interact with might be in an inconsistent state. (and you're not allowed to use mutexes or other synchronization from a signal handler, either -- signals are pretty evil that way)
However, if you don't like the idea of having to poll a boolean all the time, one other thing you can do from within a signal handler (at least on most OS's) is send a byte on a socket. So you could set up a socketpair() in advance, and have your normal event loop select() (or whatever) on the other end of the socket pair; when it receives a byte on that socket, it knows your signal handler must have sent that byte, and therefore it's time to clean up.
One other way could be to have the singleton dynamically allocated (on first use or in main), and delete it for cleanup.
Eh. I guess your PidManagerPtr actually points to a dynamically allocated object ... But doesn't boost::shared_ptr actually clean up on reallocation? So it should be enough to:
instance_ = 0;
?
Just call reset() on the shared_ptr and it'll remove your instance for you.