views:

370

answers:

5

Hi there,

In my application I am creating an object pretty much like this :

connect() {
  mVHTGlove = new vhtGlove(params);
}

and once I am about to close application I call this one :

disconnect() {
  if (mVHTGlove) 
    delete mVHTGlove;
}

This call always triggers a breakpoint with the following message :

Windows has triggered a breakpoint in DesignerDynD.exe.

This may be due to a corruption of the heap, which indicates a bug in DesignerDynD.exe or any of the DLLs it has loaded.

This may also be due to the user pressing F12 while DesignerDynD.exe has focus.

The output window may have more diagnostic information.

I cannot modify the vhtGlove class to fix the corruption of the stack as it is an external library provided only in the form of header files, lib files and dlls.

Is there any way to use this class in a clean way ?


**** EDIT ::: I tried to strip things down to a bare minimum, however I get the same results... here you have the ENTIRE code.

#include "vhandtk/vhtCyberGlove.h"
#include "vhandtk/vhtIOConn.h"
#include "vhandtk/vhtBaseException.h"

using namespace std;

int main(int argc, char* argv[])
{
   vhtCyberGlove* testGlove = NULL;

   vhtIOConn gloveAddress("cyberglove", "localhost", "12345", "com1", "115200");
   try
   {
      testGlove = new vhtCyberGlove(&gloveAddress,false);

      if (testGlove->connect())
         cout << "Glove connected successfully" << endl;
      else
      {
         throw vhtBaseException("testGlove()->connect() returned false.");
      }

      if (testGlove->disconnect())
      {
         cout << "Glove disconnected successfully" << endl;
      }
      else 
      {
         throw vhtBaseException("testGlove()->disconnect() returned false.");
      }

   }
   catch (vhtBaseException *e)
   {
      cout << "Error with gloves: " << e << endl;
      system("pause");
      exit(0);
   }

   delete testGlove;

   return 0;
}

Still crashes on deletion of the glove.


EDIT #2 :: If I just allocate and delete an instance of vhtCyberGlove it also crashes.

int main(int argc, char* argv[])
{
   vhtCyberGlove* testGlove = NULL;
   vhtIOConn gloveAddress("cyberglove", "localhost", "12345", "com1", "115200");
   testGlove = new vhtCyberGlove(&gloveAddress,false);
   delete testGlove; //<<crash!
   return 0;
}

Any ideas?

thanks!

JC

+2  A: 

The heap corruption error is reported when the vhtGlove is deleted. However, it may just as well be your own code that causes the corruption. This often happens as a result of overwriting a buffer allocated on the heap, perhaps from a call to malloc. Or you are perhaps deleting the same object twice. You can avoid this by using a smart pointer like std::auto_ptr to store the pointer to the object.

Martin Liversage
Please see EDIT #2.
JC
+4  A: 

One possiblity is that mVHTGlove isn't being initialized to 0. If disconnect was then called without a connect ever being called, then you'd be attempting to deallocate a garbage pointer. Boom.

Another possibility is that you are actually corrupting the stack a bit before that point, but that is where the corruption actually causes the crash. A good way to check that would be to comment out as much code as you can and still get the program to run, then see if you still get the corruption. If you don't, slowly bring back in bits of code until you see it come back.


Some further thoughts (after your edits).

You might check and see if the API doesn't have its own calls for memory management, rather than expecting you to "new" and "delete" objects manually. The reason I say this is that I've seen some DLLs have issues that looked a lot like this when some memory was managed inside the DLL and some outside.

T.E.D.
I made a stripped down version of the application to test strictly this module and .. nope. Thanks though.
JC
+1  A: 

One thing you might try to track down the source of the corruption is to look at the memory location pointed to by mVHTGlove using Visual Sudio's "Memory" window when the heap corruption is detected. See if you see anything in that memory that looks obviously like something that overran a buffer. For example, if you see a string used elsewhere in the program, then go review the code that manipulates that string -- it might be overrunning its buffer.

Nick Meyer
+1  A: 

Given vhtCyberGlove's implementation is on another DLL, I would look for heaps mismatch. In VS, for example, this would happen if the DLL is linked to the Release CRT, while your EXE is linked to the Debug CRT. When this is the case, each module uses a different heap, and as soon as you try to free memory using the wrong heap, you'll crash.

In your case, it is possible that vhtCyberGlove gets some stuff that is allocated on the other DLL, but when you delete the vhtCyberGlove instance the stuff is being deleted directly, namely referring to your heap rather than the DLL's. And when trying to free a pointer that points to another heap, your effectively corrupting yours.

If this is indeed the case, without having more details I can offer two fixes:

  1. Make sure your EXE uses the same heap as the DLL. Will probably lock you in Release mode, so it's not the best way to go
  2. Get the provider of vhtCyberGlove to manage its memory usage properly...
eran
Thank you for your answer.True there is a mismatch there, vhtCyberGlove links to MSVCRT while my app links to MSVCRT90D (naturally since I'm running it in debug).I'm not quite sure about how important this is however; I mean I've used plenty of libs in release version linked against a debug mode application and I never noticed any particular problems, I just couldn't debug the selected pieces of code. Why would it be any different now ?
JC
This depends on vhtCyberGlove. First, try that code in release mode and see if the problem goes away. If it does, that's the reason. It's hard to say without seeing more code, but I would take a good look at the header file. If it contains function definitions, their code will be using your (debug) heap. If the c'tor is all in the DLL and it allocates some memory, and the d'tor is in the header, trying to free that memory, you'll crash. If so, this is just bad programming on vhtCyberGlove's provider. Good APIs should make sure this doesn't happen, and I guess till now you've been lucky.
eran
+1  A: 

You are passing the address of a local vhtIOConn to the constructor. Is it possible that the object is assuming ownership of this pointer and trying to delete it in the destructor?

Mark Ransom
I tried allocating the vhtIOConn dynamically and passing a pointer to the constructor but it doesn't help. Also, I get the same problem with the vhtIOConn object. If I just create it and delete it the line after, bam crash.
JC
That narrows it down then. Sounds like two different heaps is the likely answer.
Mark Ransom