Jump to content

Is it good practice to NULL a pointer after deleting it?


Recommended Posts

Hiho Team,

hunting down GDI leaks I stumbled across this article:

https://stackoverflow.com/questions/1931126/is-it-good-practice-to-null-a-pointer-after-deleting-it

I check some of the standard functions, and after deletion the pointers are all still valid > isptr(x).

_GDIPlus_BitmapDispose()
_GDIPlus_ImageDispose()
_WinAPI_DeleteDC()
_WinAPI_DeleteObject()
_WinAPI_CloseHandle()

Wouldn't it make sense to adjust the standard functions (excerpt only) as follows? Pulling the pointers ByRef and explicitly setting them to NULL, if the function succeeds?

; https://stackoverflow.com/questions/1931126/is-it-good-practice-to-null-a-pointer-after-deleting-it

; ****************************************
; *******************      GDIPlus.au3
; ****************************************

; #FUNCTION# ====================================================================================================================
; Author ........: Paul Campbell (PaulIA)
; Modified.......: Gary Frost
; ===============================================================================================================================
Func _GDIPlus_BitmapDispose_Ex(ByRef $hBitmap)
    Local $aCall = DllCall($__g_hGDIPDll, "int", "GdipDisposeImage", "handle", $hBitmap)
    If @error Then Return SetError(@error, @extended, False)
    If $aCall[0] Then Return SetError(10, $aCall[0], False)

    $hBitmap = 0
    Return True
EndFunc   ;==>_GDIPlus_BitmapDispose

; #FUNCTION# ====================================================================================================================
; Author ........: Paul Campbell (PaulIA)
; Modified.......: Gary Frost
; ===============================================================================================================================
Func _GDIPlus_ImageDispose_Ex(ByRef $hImage)
    Local $aCall = DllCall($__g_hGDIPDll, "int", "GdipDisposeImage", "handle", $hImage)
    If @error Then Return SetError(@error, @extended, False)
    If $aCall[0] Then Return SetError(10, $aCall[0], False)

    $hImage = 0
    Return True
EndFunc   ;==>_GDIPlus_ImageDispose



; ****************************************
; *******************      WinAPIGdiDC.au3
; ****************************************

; #FUNCTION# ====================================================================================================================
; Author ........: Paul Campbell (PaulIA)
; Modified.......:
; ===============================================================================================================================
Func _WinAPI_DeleteDC_Ex(ByRef $hDC)
    Local $aCall = DllCall("gdi32.dll", "bool", "DeleteDC", "handle", $hDC)
    If @error Then Return SetError(@error, @extended, False)

    if $aCall[0] then $hDC = 0
    Return $aCall[0]
EndFunc   ;==>_WinAPI_DeleteDC



; ****************************************
; *******************      WinAPIHObj.au3
; ****************************************

; #FUNCTION# ====================================================================================================================
; Author ........: Paul Campbell (PaulIA)
; Modified.......:
; ===============================================================================================================================
Func _WinAPI_DeleteObject_Ex(ByRef $hObject)
    Local $aCall = DllCall("gdi32.dll", "bool", "DeleteObject", "handle", $hObject)
    If @error Then Return SetError(@error, @extended, False)

    if $aCall[0] then $hObject = 0
    Return $aCall[0]
EndFunc   ;==>_WinAPI_DeleteObject

; #FUNCTION# ====================================================================================================================
; Author ........: Paul Campbell (PaulIA)
; Modified.......:
; ===============================================================================================================================
Func _WinAPI_CloseHandle_Ex(ByRef $hObject)
    Local $aCall = DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hObject)
    If @error Then Return SetError(@error, @extended, False)

    if $aCall[0] then $hObject = 0
    Return $aCall[0]
EndFunc   ;==>_WinAPI_CloseHandle

 

Edited by KaFu
Link to comment
Share on other sites

Good practice, I don't know, maybe but not necessary in my opinion. For me it's poor programming to use disposed resources. I don't see any good case where programmer might not be aware that a resource has been release, except in poor management of resources.

When the words fail... music speaks.

Link to comment
Share on other sites

If you tell your kids to clean their room, you're done. If you go over and a room is not clean, would closing the door make it go away ?
Same with the DLL call. If I tell it to dispose, it should obliterate it out of existence and the pointer should fail to give you anything because is supposed to be gone. Else, ... you replace the stuff with Null stuff, then ask to dispose and you clear your pointer. That way if it ( the DLL ) did not do its part as well as it should, memory leak should be less. 
I claim artistic freedom. This is my work of fiction. I have no idea of anything related to DLLs and whatnot. I do have kids. 

Edit: this may be a good read ? ( gone from MSDN ).

Edited by argumentum

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

More often than not, garbage collection (GC) is not instantaneous, and calling Delete/Dispose/Close functions merely marks the parsed pointer as no longer needed (as if placing it in a bin beside the curb, but in theory still accessible until the garbage truck comes to empty it), to be physically removed (as in memory being freed) whenever the GC comes round to it. So although it's extremely unsafe to still reference the pointer after calling the disposal function, it's perfectly possible that it's still valid. Therefore it makes good sense to actively null it out yourself if there is any chance that any code might still reference it in the interim.

Link to comment
Share on other sites

2 hours ago, RTFC said:

Therefore it makes good sense to actively null it out yourself if there is any chance that any code might still reference it in the interim.

Not quite sure, but you mean it makes sense what I propose :)?

So Andreik means there's no need to update the functions, and you and argumentum would support an update?

Link to comment
Share on other sites

@KaFu Don't get me wrong, I am not against an update. I am kinda neutral on this since I don't care much if a pointer is set to null after I don't need it because I am pretty sure I won't use it anymore. :yes:

When the words fail... music speaks.

Link to comment
Share on other sites

  • 2 weeks later...
On 3/21/2024 at 7:03 PM, KaFu said:

but you mean it makes sense what I propose

Yes it does in my opinion, provided that your code does check any pointer for null before actually using it.:)

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...