🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

I don't manage to free an allocated variable

Started by
7 comments, last by Alberth 4 years, 4 months ago

Hi !

When I try to free a pointer with a delete, the program crashes on the line where I do this delete and is not freed. I don't know why. Can you help me ?

PS : the pointer which crashes when I try to delete it, is not NULL.

Advertisement

Without seeing your code (which you should show if you want people to help you). There are multiple possible issues:

  1. double deleted
  2. deleting something that wasn‘t newed.
  3. mixup between new/new[] and delete/delete[] (so array/non-array pointers)

on a side-note, delete on null(ptr) is perfectly valid and a no-op, so dont check for nullptr before delete.

that being said, unless you are stuck with C++03, don't use raw new/deletes for objects. use std::unique_ptr. Its virtually free in terms of performance, easy to learn, hard to mess up and will make you write way less code than without it.

// before

auto* pMyObject = new MyClass();
delete pMyObject;

// after
auto pMyObject = std::make_unique<MyClass>(); // thats it. auto-deallocation once pMyObject goes out of scope

For example, I have this :

struct PS_CONSTANT_BUFFER_G_BUFFER
{
	XMVECTOR cameraPosition;
	ID3D11Buffer* lightsPositions;
	unsigned int nbLights;
	bool specular;
	~PS_CONSTANT_BUFFER_G_BUFFER()
	{
		lightsPositions->Release();
		lightsPositions = NULL;
	}
};
//Then I do this:
static VS_CONSTANT_BUFFER_G_BUFFER* dataVSconstantBufferGBufferPass;

I delete with :

SafeDelete(dataVSconstantBufferGBufferPass);//the program crashes here

Which is implemented like this :

template <typename B>
    static void SafeDelete(B & pointer)
    {
        if( pointer > 0x0000000000000000)
        {
            delete pointer ;
            pointer = nullptr ;
        }
    }

theScore said:

struct PS_CONSTANT_BUFFER_G_BUFFER
{
	XMVECTOR cameraPosition;
	ID3D11Buffer* lightsPositions;
	unsigned int nbLights;
	bool specular;
	~PS_CONSTANT_BUFFER_G_BUFFER()
	{
		lightsPositions->Release();
		lightsPositions = NULL;
	}
};

This is unsafe. A pointer in a class/struct is not automatically null initialised, so it might get an invalid junk value that you then attempt to delete which will most likely crash.

At global scope you might get away with it as all global memory is initially zero, but otherwise make sure all variables are initialised before the constructor is finished so that the destructor or other stuff doesn't get broken by uninitialized values.

Also `delete nullptr` is safe, so you don't actually need that check. Also `if( pointer > 0x0000000000000000)` is a strange way to check for a null pointer, I am not even sure if it is standards compliant (is a signed pointer type allowed?), compare with `nullptr` and == or != or as a boolean (`if (pointer)`, `if (!pointer)`).

theScore said:
static VS_CONSTANT_BUFFER_G_BUFFER* dataVSconstantBufferGBufferPass;

You fail to assign an initial value to the pointer, so its value is undefined (= will contain garbage. Fix your code:

static VS_CONSTANT_BUFFER_G_BUFFER* dataVSconstantBufferGBufferPass = nullptr;

Or, and I know I'm repeating myself, just use a safe unique_ptr:

static std::unique_ptr<VS_CONSTANT_BUFFER_G_BUFFER> dataVSconstantBufferGBufferPass;

That one is automatically initialized to nullptr.

SyncViews said:
Also `delete nullptr` is safe, so you don't actually need that check. Also `if( pointer > 0x0000000000000000)` is a strange way to check for a null pointer, I am not even sure if it is standards compliant (is a signed pointer type allowed?), compare with `nullptr` and == or != or as a boolean (`if (pointer)`, `if (!pointer)`).

Or just (yeah repeating myself again). DONT check for nullptr as "delete" is absolutely fine to perform on a nullptr. A nullcheck here adds literally nothing.

Juliean said:
Also `if( pointer > 0x0000000000000000)` is a strange way to check for a null pointer, I am not even sure if it is standards compliant (is a signed pointer type allowed?)

I looked that up once, and the answer is no, the standard at the time didn't say anything about how to encode addresses or nullptr. An implementation may make any choice it considers useful.

Alberth said:
I looked that up once, and the answer is no, the standard at the time didn't say anything about how to encode addresses or nullptr. An implementation may make any choice it considers useful.

Uh, thats not my quote :D

I see now ? it's a quote bug in the editor :D

This topic is closed to new replies.

Advertisement