Advertisement

How to free memory with directx variables ?

Started by September 01, 2020 12:19 PM
7 comments, last by Juliean 4 years, 2 months ago

Hello

To free my directX pointers, I use this :

template <typename C>
    static void SafeDeleteD3Dobject(C & pointer)
    {


        if ( pointer != nullptr) 
        {
            pointer->Release();
            pointer = nullptr;
        }
    }

I pass the address of the directX variable as a parameter, but the program always goes in the if block, and the problem it is that it goes inside even if the address is equal to 0x0000000000.

How should I do ?

I have another question : I read that it is better to assign the pointer to nullptr or NULL with old C++ but I don't understand why ?

theScore said:

I pass the address of the directX variable as a parameter…

Yeah, but it's a function template - how can you be sure that it's a pointer? What is C? First and foremost, it's a reference to C. Not sure if they should be compared to nullptr.

theScore said:

I read that it is better to assign the pointer to nullptr or NULL with old C++ but I don't understand why ?

It's a preference - but nullptr is the new thing and here to stay.

Advertisement

theScore said:
nullptr or NULL with old C++ but I don't understand why ?

It is simple a matter of safety. NULL is defined as 0 (zero) so assigning 0 to a pointer sets it's address to zero and the pointer is invalid in case of

if(ptr)
{...}

which you should use instead of your equality check because the compiler will throw errors for some types that don't be equotable.

However, what happens if you try to pass NULL to a function that has overloads for a pointer and an arithmetic value, how do you deduce which overload to use? The answer is that it will simply set the value to 0 rather than passing the pointer as a null pointer, so this is considered to be bad.

I'm still using old C++ code and made my own null_ptr implementation that is simply defined as

/**
 Null-Pointer Type
*/
const struct 
{
    public:
        template<class T> force_inline operator T*() const
        {
            return 0;
        }
        template<class C, class T> force_inline operator T C::*() const
        {
            return 0;
        }

    private:
        void force_inline operator&() const {}

} NullPointer = { };

As you can see, the code has two operators that both return certain kind of pointer which is deduced at compile time. Now you can pass NullPointer to a function and will always invoke the pointer overload

theScore said:

Hello

To free my directX pointers, I use this :

template <typename C>
    static void SafeDeleteD3Dobject(C &amp; pointer)
    {


        if ( pointer != nullptr) 
        {
            pointer->Release();
            pointer = nullptr;
        }
    }

I pass the address of the directX variable as a parameter, but the program always goes in the if block, and the problem it is that it goes inside even if the address is equal to 0x0000000000.

How should I do ?

I have another question : I read that it is better to assign the pointer to nullptr or NULL with old C++ but I don't understand why ?

I Tested your SafeDeleteD3Dobject function and it doesn't enter the if block if the pointer is nullptr. Are you sure the error is not elsewhere?

I have found that when it crashes, it is because sometimes, the variable's address is rather 0x0000000000 or 0xFFFFFFFFFF.

And it crashed because my program didn't managed these values.

theScore said:
sometimes, the variable's address is rather 0x0000000000 or 0xFFFFFFFFFF

Smells like you did not initialize the variable properly. You should always ensure that everything in a class as well as on the stack is initialized properly to a default value or else RAM trash will break your neck.

Visual Studio for example will hide that in debug mode but not in release builds

Advertisement

theScore said:

I have another question : I read that it is better to assign the pointer to nullptr or NULL with old C++ but I don't understand why ?

Consider what would happen if you called SafeDeleteD3Dobject twice on the same pointer.

Clearing the pointer plus a nullptr check before calling Release() prevents you from accidentally calling Release() more than AddRef was - from "double-deleting" the object.

theScore said:
I have another question : I read that it is better to assign the pointer to nullptr or NULL with old C++ but I don't understand why ?

Actually, you shouldn't always do that. You should only really do it when you release a variable that you intend to reuse; or that at least could potentially be reused in the given context.

Assigning null when releasing/deleting objects in other situations is eigther meaningless or just masks other problems. I'm mostly talking of destructors. Never null a variable in a destructor, because its a) pointless and b) would hide problems that happen when the actual destructor is called twice (which is highly unlikely unless you are doing manual memory managment).

Or when you store objects in a vector and have to iterate over it to free the objects. What would you rather have happen? The loop silently failing to release all the objects because you forgot to increment “i” with the null-assignment; or have it pretty much 100% crash on the spot when trying to delete the same object multiple times? (yeah a pretty constructed problem, but still).
When shipping an app, you might actually still prefer the first case; but for general development you will want things to fail quick and fast instead of hiding problems by allowing more invalid code to run without issues.

This topic is closed to new replies.

Advertisement