Hey all!

I'm writing a simple fluid game in C++, and I've come across a strange issue. I allocate a whole bunch of arrays of float for use in simulations. During the course of the program, nothing goes wrong. But when I try to delete the arrays, I get a SIGTRAP error (on windows using MinGW). This is a problem as I need to delete the arrays whenever I resize the game.

Here's the code where I initialize the arrays:

if(!inited){
		//easy
		sizexy=sxy;
		size=sizexy.x*sizexy.y;
		#define FLOATSPACE (float*)malloc(size*sizeof(float))
		div = FLOATSPACE;
		velx = FLOATSPACE;
		vely = FLOATSPACE;
		velx0 = FLOATSPACE;
		vely0 = FLOATSPACE;
		accx = FLOATSPACE;
		accy = FLOATSPACE;
		dens = FLOATSPACE;
		dens0 = FLOATSPACE;
		#undef FLOATSPACE
		inited=true;
	}

In that code, sxy is just a struct containing two ints, x and y. They are never negative, so that's not the issue. That part of the code runs fine and never gives me any problems.

But here's the code where I delete the arrays:

Game::~Game(){
	free(velx);		//this line gives SIGTRAP
	free(vely);		//changing the order doesn't matter
	free(velx0);
	free(vely0);
	free(accx);
	free(accy);
	free(dens);
	free(dens0);
	free(div);
}

I know for a fact that all of those arrays (they are float* ) are either NULL or have been initialized with (float*)malloc(size*sizeof(float)) . I also know that my application is memory safe otherwise. Other parts of the game don't use dynamic memory. Other parts of my application do, but that's code that wrote years ago and use everywhere, it's guaranteed to be correct.

Any help?

Thanks.

What is the class (NoClass?) at the bottom of your post for? And not to be picky but this is the C++ forum and you're posting C code :)

have you tried to use the new and delete function instead of C functions?

float * velx = new float[size];

// later on

delete [] velx;
velx = 0;
//or
velx = NULL;

What is the class (NoClass?) at the bottom of your post for? And not to be picky but this is the C++ forum and you're posting C code :)

That is a little piece of contradictory code that is my signature. Feel free to ignore it.

Yes, I'm posting object oriented C code, with destructors and all.

As a matter of fact, I have been using the new and delete operators before, when I started getting this error. I switched to C-style malloc/free to see if it changed anything. It did not.

The problem only happens when I delete(free) any of these arrays. Before, that would happen whenever I resized the game. I turned off resizing to check, and now it happens whenever I close the game (the destructor is called).
I have checked with the debugger. The first delete/free statement in the destructor is the one that causes the SIGTRAP. If I move them around, it doesn't matter. Whichever one is first is the one that will give SIGTRAP.

This is all part of an open source game I'm writing. If you want, you can look at the original source code here: http://code.google.com/p/openpowder/source/browse/#svn/trunk/SDL_APP/src
The object in question is Flob.cpp at the top of the list.

In the interests of debugging, please include a null check before you delete (free) the array's.

if(velx)
 delete [] velx;

If this stops the SIGTRAP then the problem lies somewhere else in your code because the arrays are being assigned NULL for some reason (possibly causing a memory leak)

EDIT: I know you already said that you know they are either null or assigned. But trying to delete a null pointer will throw an exception.

Edited 6 Years Ago by Ketsuekiame: n/a

I realized it was your signature after I posted my comment, sorry about that, long day at work :( Ketsuekiame is correct, trying to delete a NULL pointer will cause an exception, I know it has caused me a few headaches in the past. Hopefully that solves your problem.

Edited 6 Years Ago by ctaylo21: n/a

Actually deleting a null pointer or one that has been set to zero is perfectly safe. Trying to delete a pointer again before setting it to null or 0 is not safe. Here is a link to the MSDN page I'm using for my argument. http://msdn.microsoft.com/en-us/library/h6227113%28VS.80%29.aspx

Although this is true for for MSVC is it also true when using MinGW?

Also, when did MS change that behaviour. It wasn't 2 years ago that deleting a null pointer would throw an exception in code. I've always done a null check since. Obviously I've never bothered to check since ;)

Deleting a null pointer will throw an exception but it is safe to do. I was able to call delete on null pointers back when I had MSVC++ 6.0. here is a little piece of the c++98 standard. This is from 3.7.3.2 paragraph 3

The value of the first parameter supplied to a deallocation function shall be a null pointer value, or refer to storage allocated by the corresponding allocation function (even if that allocation function was called with a zero argument). If the value of the first argument is a null pointer value, the call to the deallocation function has no effect. If the value of the first argument refers to a pointer already deallocated, the effect is undefined.

Deleting a null pointer will throw an exception but it is safe to do.

Which could be the cause of the SIGTRAP.

I realise that it is "safe" to do so, but th way you said it led me to believe it didn't throw.

It could just be that it's throwing an exception on the attempt to delete the null pointer and hence flagging up the SIGTRAP.

EDIT: Clarifying my reasoning for saying he could have a memory leak. If he's set the pointer to NULL somewhere without deleting it (which if he's lost track of the pointer is certainly possible) then it would cause a leak.

Edited 6 Years Ago by Ketsuekiame: n/a

Yes that would. He said he had a operator precedence problem that he fixed and it works now.

Edited 6 Years Ago by NathanOliver: n/a

I never mentioned anything about operator precedence or it being fixed. The fact is that the issue is still present.

What's strange is that it's only those arrays.

Elsewhere in my code I'm able to create and delete arrays (even delete NULL pointers) without a single problem.

I've gone over every line that accesses these arrays with a fine comb. Not once do I do anything illegal with them. I'll admit that I use what would appear like strange pointer arithmetic. That's because these arrays represent 2D grids of values, and going through only the borders requires some math. But it's relatively straightforward.

You can see the original source code here:
http://code.google.com/p/openpowder/source/browse/trunk/SDL_APP/src/Flob.cpp

The function that gives this problem is right at the top. It's Flob::~Flob() . The constructor right above that initializes the arrays to NULL, and the resize function below allocates the arrays.

First off, using delete on a null pointer never throws and is perfectly okay.
A SIGTRAP can indicate memory corruption or a double free. Remember that the memory corruption does not necessarily need to occur in Flob.cpp.
You also should consequently use new and delete/delete[] in your programs to avoid any problems.

First off, using delete on a null pointer never throws and is perfectly okay.
A SIGTRAP can indicate memory corruption or a double free. Remember that the memory corruption does not necessarily need to occur in Flob.cpp.
You also should consequently use new and delete/delete[] in your programs to avoid any problems.

I swear it used to do. Attempting to delete a null pointer caused me no end of issues through university so I always ended up null checking the pointer first. This may have been a quirk of MSVC though.

(If I go through all my old Uni code I've null checked everything and left comments like // Check for null so not to throw exception )

I even have a safe delete macro in my later work #define SAFEDEL(ptr) if(ptr != NULL) { delete ptr; ptr = NULL; } So it's just something I've always done since.


You are of course, correct. I've tested it in VS2008 and it deletes NULL perfectly fine. It must have just been the compiler I was using at the time doing something odd. (VS2005 w/ OpenGL Headers Included)

Edited 6 Years Ago by Ketsuekiame: n/a

I swear it used to do. Attempting to delete a null pointer caused me no end of issues through university so I always ended up null checking the pointer first. This may have been a quirk of MSVC though.

I suppose that's possible. I assume this was before the first C++ standard was released?
Nevertheless, it should no longer be done, as delete does nothing when the pointer is 0. An additional check is redundant.

Edited 6 Years Ago by Aranarth: n/a

I suppose that's possible. I assume this was before the first C++ standard was released?
Nevertheless, it should no longer be done, as delete does nothing when the pointer is 0. An additional check is redundant.

No idea but Microsoft has never been one to conform to standards, just look at IE! *whistles innocently*

In any case, I can't argue against what you've said. Now I know that, I won't bother with the redundant NULL check in future.

11 years on and still learning. =)

I went back to the C++ style new/delete statements. Of course, this changed absolutely nothing at all.

Here's my new destructor. I put in a few simple test statements just to make sure. When I delete any array of floats, it works. But when I delete the arrays for my game, I get SIGSEGV. Here's the code:

Flob::~Flob(){
	//delete null test
	delete [] (char*)NULL;		//this line works OK
	//simple delete test
	delete new int;			//this line works OK
	delete [] new int[10];		//this line works OK
	delete [] new float[10];	//this line works OK
	//now the problem area
	delete [] velx;				//this line gives SIGSEGV
	delete [] vely;
	delete [] velx0;
	delete [] vely0;
	delete [] accx;
	delete [] accy;
	delete [] dens;
	delete [] dens0;
	delete [] diverg;
	//this line is superfluous!
	velx=vely=velx0=vely0=accx=accy=dens=dens0=diverg=NULL;
}

Any ideas?

On POSIX-compliant platforms, SIGSEGV is the signal sent to a process when it makes an invalid memory reference, or segmentation fault.

Link

Based on the above, are you sure your pointer is valid at that point? has it been deleted before hand but not assigned to NULL?

You haven't mixed malloc with delete right?

Edited 6 Years Ago by Ketsuekiame: n/a

Where do you use the Flob class? if you are making copies of objects that might be your problem since you don have a copy constructor defined. What would happen if you add a copy constructor to your Flob class?

Where do you use the Flob class? if you are making copies of objects that might be your problem since you don have a copy constructor defined. What would happen if you add a copy constructor to your Flob class?

The copy constructor and assignment operator for the Flob class are private. I never make copies of that class, nor do I intend to be able to.

I know what a SIGSEGV is. It just means you're trying to access memory that does not belong to your program, generally memory that you deleted before. This is not the problem that I'm having. The problem is SIGTRAP. It happens when I delete a particular set of arrays. What's strange is that it ONLY happens for those arrays, not for others. And I know that this is not a problem with me deleting them somewhere else because the only place where they are deleted is in the destructor that I show you a few posts back. And I access those arrays constantly before that, in nearly every function (none of which give me any errors).

This is what I need help with.

I saw your private copy constructor in Flob.h but I do not see it defined in Flob.cpp so that might be why. If it is defined somewhere let me know so i can take a look. It might not be the copy constructor but better to make sure it isn't it right?

I see your point there. I figured if I declare it in the header, the compiler would assume that I intend to implement it, and give me an error wherever it would be used. What I'll do right now is try to make it do something like throw "Flob Should never be copied!"; . If the application is making shallow copies somewhere, then that would cause these kinds of problems. Though I really would expect a SIGSEGV instead of a SIGTRAP.

This article has been dead for over six months. Start a new discussion instead.