Questions about C++ memory allocation and delete - c++

I'm getting a bad error. When I call delete on an object at the top of an object hierarchy (hoping to the cause the deletion of its child objects), my progam quits and I get this:
*** glibc detected *** /home/mossen/workspace/abbot/Debug/abbot: double free or corruption (out): 0xb7ec2158 ***
followed by what looks like a memory dump of some kind. I've searched for this error and from what I gather it seems to occur when you attempt to delete memory that has already been deleted. Impossible as there's only one place in my code that attempts this delete. Here's the wacky part: it does not occur in debug mode. The code in question:
Terrain::~Terrain()
{
if (heightmap != NULL) // 'heightmap' is a Heightmap*
{
cout << "heightmap& == " << heightmap << endl;
delete heightmap;
}
}
I have commented out everything in the heightmap destructor, and still this error. When the error occurs,
heightmap& == 0xb7ec2158
is printed. In debug mode I can step through the code slowly and
heightmap& == 0x00000000
is printed, and there is no error. If I comment out the 'delete heightmap;' line, error never occurs. The destructor above is called from another destructor (separate classes, no virtual destructors or anything like that). The heightmap pointer is new'd in a method like this:
Heightmap* HeightmapLoader::load() // a static method
{
// ....
Heightmap* heightmap = new Heightmap();
// ....other code
return heightmap;
}
Could it be something to do with returning a pointer that was initialized in the stack space of a static method? Am I doing the delete correctly? Any other tips on what I could check for or do better?

What happens if load() is never called? Does your class constructor initialise heightmap, or is it uninitialised when it gets to the destructor?
Also, you say:
... delete memory that has already been deleted. Impossible as there's only one place in my code that attempts this delete.
However, you haven't taken into consideration that your destructor might be called more than once during the execution of your program.

In debug mode pointers are often set to NULL and memory blocks zeroed out. That is the reason why you are experiencing different behavior in debug/release mode.
I would suggest you use a smart pointer instead of a traditional pointer
auto_ptr<Heightmap> HeightmapLoader::load() // a static method
{
// ....
auto_ptr<Heightmap> heightmap( new Heightmap() );
// ....other code
return heightmap;
}
that way you don't need to delete it later as it will be done for you automatically
see also boost::shared_ptr

It's quite possible that you're calling that dtor twice; in debug mode the pointer happens to be zeroed on delete, in optimized mode it's left alone. While not a clean resolution, the first workaround that comes to mind is setting heightmap = NULL; right after the delete -- it shouldn't be necessary but surely can't hurt while you're looking for the explanation of why you're destroying some Terrain instance twice!-) [[there's absolutely nothing in the tiny amount of code you're showing that can help us explain the reason for the double-destruction.]]

It looks like the classic case of uninitialized pointer. As #Greg said, what if load() is not called from Terrain? I think you are not initializing the HeightMap* pointer inside the Terrain constructor. In debug mode, this pointer may be set to NULL and C++ gurantees that deleting a NULL pointer is a valid operation and hence the code doesn't crash. However, in release mode due to optimizations, the pointer in uninitialized and you try to free some random block of memory and the above crash occurs.

Related

Bizzare nullref in C++

I have a small piece of C++ code that is making me insane. Whenever it runs, it throws a null reference exception in a very unexpected place.
void CSoundHandle::SetTarget(CSound* sound)
{
assert(_Target == nullptr);
if (sound == nullptr) { return; }
_Target = sound;
// This works just fine.
_Target->Play();
// This is the code that throws the exception. It doesn't seem possible, as
// we should not be able to get here if 'sound' is null.
_Target->Stop();
}
So what the heck is going on? The message in the output window is:
this->_Target-> was nullptr.
0xC0000005: Access violation reading location 0x00000014
I have confirmed in disassembly that it is not taking place inside of the Stop function as well. How is this possible?
EDIT:
The pointer for sound is indeed initialized, and 'this' and 'this->Target' are non-null.
EDIT 2:
I have somehow solved the problem by slightly changing the declaration of the Stop function:
// From this.
virtual void Stop();
// To this.
void Stop();
This seems especially odd since Play() is also virtual, but works without any trouble. I can't say I've ever seen anything like this before. There are no other functions named 'Stop' in the rest of the program, nor are there subclasses of CSound, so I'm a bit confused.
Reading location 0x00000014 implies you're trying to access a field located 0x14 bytes from the beginning of an object. The pointer to that object is set to null. So the problem is in the caller of your function: it passes a bad pointer to sound, which is neither null nor valid. This is why the null check in your function passes (0x14 isn't null), but you still crash.
Update:
The second edit to the question indicates the problem is in calling a virtual function. The null here is the virtual pointer then, and 0x14 is the offset of the Stop virtual function. The virtual pointer is set (in code generated by the compiler) during object construction, and should never point to 0. If it does, some part of the program is corrupting the object. An easy to detect case would be an attempt to reset the object, but memory corruptions (e.g., out-of-bound write to an array) could also cause this issue.

Assertion when operator delete is called

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

Subtle Memory Leak, and is this common practice?

I think I might be creating a memory leak here:
void commandoptions(){
cout<< "You have the following options: \n 1). Buy Something.\n 2).Check you balance. \n3). See what you have bought.\n4.) Leave the store.\n\n Enter a number to make your choice:";
int input;
cin>>input;
if (input==1) buy();
//Continue the list of options.....
else
commandoptions(); //MEMORY LEAK IF YOU DELETE THE ELSE STATEMENTS!
}
inline void buy(){
//buy something
commandoptions();
}
Let's say commandoptions has just exectued for the first time the program has been run. The user selects '1', meaning the buy() subroutine is executed by the commandoptions() subroutine.
After buy() executes, it calls commandoptions() again.
Does the first commandoptions() ever return? Or did I just make a memory leak?
If I make a subroutine that does nothing but call itself, it will cause a stackoverflow because the other 'cycles' of that subroutine never exit. Am I doing/close to doing that here?
Note that I used the inline keyword on buy... does that make any difference?
I'd happily ask my professor, he just doesn't seem available. :/
EDIT: I can't believe it didn't occur to me to use a loop, but thanks, I learned something new about my terminology!
A memory leak is where you have allocated some memory using new like so:
char* memory = new char[100]; //allocate 100 bytes
and then you forget, after using this memory to delete the memory
delete[] memory; //return used memory back to system.
If you forget to delete then you are leaving this memory as in-use while your program is running and cannot be reused for something else. Seeing that memory is a limited resource, doing this millions of times for example, without the program terminating, would end you with no memory left to use.
This is why we clean up after ourselves.
In C++ you'd use an idiom like RAII to prevent memory leaks.
class RAII
{
public:
RAII() { memory = new char[100]; }
~RAII() { delete[] memory }
//other functions doing stuff
private:
char* memory;
};
Now you can use this RAII class, as so
{ // some scope
RAII r; // allocate some memory
//do stuff with r
} // end of scope destroys r and calls destructor, deleting memory
Your code doesn't show any memory allocations, therefore has no visible leak.
Your code does seem to have endless recursion, without a base case that will terminate the recursion.
Inline keyword won't cause a memory leak.
If this is all the code you have, there shouldn't be a memory leak. It does look like you have infinite recursion though. If the user types '1' then commandoptions() gets called again inside of buy(). Suppose they type '1' in that one. Repeat ad infinum, you then eventually crash because the stack got too deep.
Even if the user doesn't type '1', you still call commandoptions() again inside of commandoptions() at the else, which will have the exact same result -- a crash because of infinite recursion.
I don't see a memory leak with the exact code given however.
This is basically a recursion without a base case. So, the recursion will never end (until you run out of stack space that is).
For what you're trying to do, you're better off using a loop, rather than recursion.
And to answer your specific questions :
No, commandoptions never returns.
If you use a very broad definition of a memory leak, then this is a memory leak, since you're creating stack frames without ever removing them again. Most people wouldn't label it as such though (including me).
Yes, you are indeed gonna cause a stack overflow eventually.
The inline keyword won't make a difference in this.
This is not about memory leak, you are making infinite calls to commandoptions function no matter what the value of input is, which will result in stack crash. You need some exit point in your commandoptions function.
There is no memory leak here. What does happen (at least it looks that way in that butchered code snippet of yours) is that you get into an infinite loop. You might run out of stack space if tail call optimization doesn't kick in or isn't supported by your compiler (it's a bit hard to see whether or not your calls actually are in tail position though).

Freeing a valid SDL surface results in segfault

[SOLVED] Forgot to implement a copy constructor and an assignment operator. The instance which is being assigned to using default copying will get the same pointer as the instance which created the surface it points to. Once one of them destructs or calls redraw(), the other keeps the pointer to freed memory, and it causes a segmentation fault.
I have a class for text labels in my application. When it's properties are changed, it automatically redrawing itself into it's private surface.
Generally, redrawing looks like this:
void Text::redraw() {
if(_font==0) return;
if(_image) {
SDL_FreeSurface(_image); //this line throwing a segfault
_image = 0;
}
_image = TTF_RenderUTF8_Blended(_font, _text.c_str(), _color);
}
But the code crashing on freeing the surface (only a valid ones, of course, as the pointer equals to 0 when it doesn't have a surface to free).
It's also strange that on some machines the code's doing well and frees a memory. But on the others it crashes.
If I comment out lines where it frees a surface, the application works well, but the memory leaks. I didn't found nor explanation, neither a solution for that.
I do set _image to 0 in constructor. There is no code that changes _image value or frees the surface except redraw() function (and destructor).
Somehow freeing memory crashing on XP only. If I comment out freeing part, it doesn't crash. Both variants works on win7 (both x86 and x64) well.
Taking the premise that that we generally know that SDL works well this leaves us with the following options (I can't think of any others, but there may well be some)
Possibility that the library was built incorrectly
The enclosing Text is somehow being copied somewhere else in the code (breaking the rule of 3
Something else is calling SDL_FreeSurface with the same pointer
Something else is trampling on the heap (possibly but unlikely as this is the only instance you've said that fails);
So I'd generally debug this by adding some (grep'able) printfs as follows and then check the output line by line:
void Text::redraw() {
if(_font==0) return;
if(_image) {
fprintf(stderr,"## $%x freeing $%x",this, _image);
SDL_FreeSurface(_image);
_image = 0;
}
_image = TTF_RenderUTF8_Blended(_font, _text.c_str(), _color);
fprintf(stderr,"## $%x allocated $%x",this, _image);
}

Dealing with an object corrupting the heap

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
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.
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.
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.
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:
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
Get the provider of vhtCyberGlove to manage its memory usage properly...
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?