Page 1 of 1
Checking if memory is valid
Posted: Wed Apr 16, 2014 10:55 pm
by Dreamland Fantasy
Hi there,
I'm looking for a way to verify if a memory ID is valid. As an example, take the following code:
Code: Select all
*mem = AllocateMemory(1024)
Debug *mem
Debug MemorySize(*mem) ; Valid memory ID here
FreeMemory(*mem)
Debug *mem
Debug MemorySize(*mem) ; Not a valid memory ID anymore
Essentially what I am wanting to do is create a procedure that takes a memory ID as a parameter, but I want to verify that it is valid so that it can return with a fail code if necessary.
Kind regards,
Francis
Re: Checking if memory is valid
Posted: Wed Apr 16, 2014 11:14 pm
by Thunder93
Code: Select all
*MemoryID = AllocateMemory(1000)
*Pointer = *MemoryID
CopyMemoryString("Hello ", @*Pointer)
CopyMemoryString("World")
*NewMemoryID = ReAllocateMemory(*MemoryID, 2000) ; need more memory
If *NewMemoryID
; work with *NewMemoryID now with size 2000
;
Debug "The old content is still here:"
Debug PeekS(*NewMemoryID)
FreeMemory(*NewMemoryID)
Else
; resizing failed, keep working with *MemoryID (size 1000)
;
FreeMemory(*MemoryID)
EndIf
Example from help

Re: Checking if memory is valid
Posted: Wed Apr 16, 2014 11:32 pm
by Dreamland Fantasy
Unless I'm missing something (which is entirely possible), I don't see how that solves my problem. I've updated my example to give a better reflection of what I am trying to achieve:
Code: Select all
Procedure MyProc(*mem)
Debug *mem
If *mem ; I want to check if *mem is valid
Debug MemorySize(*mem)
Else
ProcedureReturn 0 ; *mem not valid, so fail
EndIf
EndProcedure
*mem = AllocateMemory(1024)
MyProc(*mem) ; Valid memory ID here
FreeMemory(*mem)
MyProc(*mem) ; Not a valid memory ID anymore
Kind regards,
Francis
Re: Checking if memory is valid
Posted: Thu Apr 17, 2014 12:22 am
by Thunder93
You mean like the way the following does... ?
Code: Select all
Procedure MyProc(*mem)
If *mem ; I want to check if *mem is valid
Debug "*mem is valid"
Else
Debug "*mem isn't valid"
ProcedureReturn 0 ; *mem not valid, so fail
EndIf
EndProcedure
*mem = AllocateMemory(1024)
MyProc(*mem) ; Valid memory ID here
FreeMemory(*mem) : *mem = 0
MyProc(*mem) ; Not a valid memory ID anymore
Re: Checking if memory is valid
Posted: Thu Apr 17, 2014 12:36 am
by Dreamland Fantasy
But the procedure would still produce an error if garbage is put into the parameter. I want to check if what is passed is valid, something like an IsMemory(*mem) function.
Kind regards,
Francis
Re: Checking if memory is valid
Posted: Thu Apr 17, 2014 12:42 am
by Thunder93
What you are looking for, it has been requested in the past.
First read thoroughly
Re: Checking if memory is valid
Posted: Thu Apr 17, 2014 12:51 am
by Dreamland Fantasy
Many thanks for those links.
So, in a nutshell, having an IsMemory() function is bad programming practice. I'll need to have a think about redesigning that part of my code then.
Kind regards,
Francis
Re: Checking if memory is valid
Posted: Thu Apr 17, 2014 5:03 pm
by JHPJHP
Not sure if the following helps...
- Windows only
I used the [ divide by 0 ] exception to demonstrate how it works, but maybe there is an exception that fits your requirements:
Code: Select all
Procedure UnhandledExceptionFilter(*ep.EXCEPTION_POINTERS)
ExceptionCode = *ep\ExceptionRecord\ExceptionCode
ExceptionFlags = *ep\ExceptionRecord\ExceptionFlags
Select ExceptionCode
Case #EXCEPTION_ACCESS_VIOLATION
ExceptionFlags = 1
ErrorMessage.s = "EXCEPTION_ACCESS_VIOLATION"
Case #EXCEPTION_ARRAY_BOUNDS_EXCEEDED
ErrorMessage.s = "EXCEPTION_ARRAY_BOUNDS_EXCEEDED"
Case #EXCEPTION_BREAKPOINT
ErrorMessage.s = "EXCEPTION_BREAKPOINT"
Case #EXCEPTION_DATATYPE_MISALIGNMENT
ErrorMessage.s = "EXCEPTION_DATATYPE_MISALIGNMENT"
Case #EXCEPTION_FLT_DENORMAL_OPERAND
ErrorMessage.s = "EXCEPTION_FLT_DENORMAL_OPERAND"
Case #EXCEPTION_FLT_DIVIDE_BY_ZERO
ErrorMessage.s = "EXCEPTION_FLT_DIVIDE_BY_ZERO"
Case #EXCEPTION_FLT_INEXACT_RESULT
ErrorMessage.s = "EXCEPTION_FLT_INEXACT_RESULT"
Case #EXCEPTION_FLT_INVALID_OPERATION
ErrorMessage.s = "EXCEPTION_FLT_INVALID_OPERATION"
Case #EXCEPTION_FLT_OVERFLOW
ErrorMessage.s = "EXCEPTION_FLT_OVERFLOW"
Case #EXCEPTION_FLT_STACK_CHECK
ErrorMessage.s = "EXCEPTION_FLT_STACK_CHECK"
Case #EXCEPTION_FLT_UNDERFLOW
ErrorMessage.s = "EXCEPTION_FLT_UNDERFLOW"
Case #EXCEPTION_ILLEGAL_INSTRUCTION
ErrorMessage.s = "EXCEPTION_ILLEGAL_INSTRUCTION"
Case #EXCEPTION_IN_PAGE_ERROR
ErrorMessage.s = "EXCEPTION_IN_PAGE_ERROR"
Case #EXCEPTION_INT_DIVIDE_BY_ZERO
ErrorMessage.s = "EXCEPTION_INT_DIVIDE_BY_ZERO"
Case #EXCEPTION_INT_OVERFLOW
ErrorMessage.s = "EXCEPTION_INT_OVERFLOW"
Case #EXCEPTION_INVALID_DISPOSITION
ErrorMessage.s = "EXCEPTION_INVALID_DISPOSITION"
Case #EXCEPTION_NONCONTINUABLE_EXCEPTION
ErrorMessage.s = "EXCEPTION_NONCONTINUABLE_EXCEPTION"
Case #EXCEPTION_PRIV_INSTRUCTION
ErrorMessage.s = "EXCEPTION_PRIV_INSTRUCTION"
Case #EXCEPTION_SINGLE_STEP
ErrorMessage.s = "EXCEPTION_SINGLE_STEP"
Case #EXCEPTION_STACK_OVERFLOW
ErrorMessage.s = "EXCEPTION_STACK_OVERFLOW"
Default
ExceptionFlags = 1
ErrorMessage.s = "EXCEPTION_UNKNOWN"
EndSelect
If ExceptionFlags
ExceptionType.s = Chr(10) + Chr(10) + "EXCEPTION_NONCONTINUABLE"
Else
ExceptionType.s = Chr(10) + Chr(10) + "EXCEPTION_CONTINUABLE"
EndIf
MessageRequester("Error", ErrorMessage + ExceptionType)
If ExceptionFlags
SetUnhandledExceptionFilter_(#Null)
Result = #EXCEPTION_EXECUTE_HANDLER
If #PB_Compiler_Debugger : End : EndIf
Else
*ep\ContextRecord\Eip + 2
Result = #EXCEPTION_CONTINUE_EXECUTION
EndIf
ProcedureReturn Result
EndProcedure
Macro TRY
DisableDebugger
SetUnhandledExceptionFilter_(@UnhandledExceptionFilter())
EndMacro
Macro ENDTRY
SetUnhandledExceptionFilter_(#Null)
EnableDebugger
EndMacro
Procedure MyProc(*mem)
Debug *mem
If *mem
TRY
x / MemorySize(*mem)
ENDTRY
Else
ProcedureReturn 0
EndIf
EndProcedure
*mem = AllocateMemory(1024)
MyProc(*mem)
FreeMemory(*mem)
MyProc(*mem)
MessageRequester("Test", "Occurred after exception.")
Here is another example:
Code: Select all
Procedure SafePlace()
MessageRequester("Warning", "An error has been encountered, and the application will be closed.")
SetUnhandledExceptionFilter_(#Null)
End
EndProcedure
Procedure UnhandledExceptionFilter(*ep.EXCEPTION_POINTERS)
*ep\ExceptionRecord\ExceptionFlags = 0
*ep\ContextRecord\Eip = @SafePlace()
ProcedureReturn #EXCEPTION_CONTINUE_EXECUTION
EndProcedure
SetUnhandledExceptionFilter_(@UnhandledExceptionFilter())
RaiseException_(#EXCEPTION_ACCESS_VIOLATION, #EXCEPTION_NONCONTINUABLE, #Null, #Null)
SetUnhandledExceptionFilter_(#Null)
Re: Checking if memory is valid
Posted: Thu Apr 17, 2014 5:17 pm
by Thunder93
That version of code is Windows x86 platforms only.
Re: Checking if memory is valid
Posted: Thu Apr 17, 2014 5:35 pm
by Dreamland Fantasy
Thanks JHPJHP for those examples, but I need something that is going to be compatible across multiple platforms.
My current solution is to use a structure to store the memory pointer and other details, and check if these are valid. It seems to work, but I'll need to test it further to be sure that it will work in all cases.
Kind regards,
Francis