IsMemory()

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

IsMemory()

Post by Rescator »

I got no idea if this will work "as is",
anyway I was surprised to see no search hits on "ismemory" on the forum at all, any chance of this being implemented?

Code: Select all

/*
 *  IsMemory() command for PureBasic
 */

#include "MemoryPLUGIN.h"


M_PBFUNCTION int PB_IsMemory(char *Memory)
{
  return HeapValidate(PB_Memory_Heap, 0, Memory);
}
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Post by Rescator »

Crap, just noticed in the PSDK that HeapValidate() exist in the NT (4.x/5.x/6.x) kernel only...
Hmm. Sorry Fred... Any other way to make a IsMemory() then?
Last edited by Rescator on Mon Nov 13, 2006 8:31 pm, edited 1 time in total.
Fred
Administrator
Administrator
Posts: 18162
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Post by Fred »

Good code for windows, what about one for linux ? :)
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Post by Rescator »

Maybe use HeapSize() instead as that exist on all Windows and the PSDK states:
If the function succeeds, the return value is the size of the allocated memory block, in bytes.

If the function fails, the return value is (SIZE_T) -1. The function does not call SetLastError. An application cannot call GetLastError for extended error information.
Although the "(SIZE_T) -1" is a bit confusing I assume this means it returns -1 on failure or does it mean ($FFFFFFFF)-1 ?

In any case if heapsize return -1 this would mean failure and IsMemory() would be made to return #False, if all is ok IsMemory() would be made to return #True

Currently MemorySize() can't be used to test if memory is valid (debugger throws up an error, and a compiled program crashes)
So cloning MemorySize() naming it IsMemory() and making sure it returns #False or #True rather than crashing should work ok on any windows version, and hopefully Linux and Mac as well or?
Fred
Administrator
Administrator
Posts: 18162
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Post by Fred »

Unfortunately, it's not possible to do that on linux/mac IIRC.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

IsMemory() should not be implemented. There's probably other uses for it (or?), but I imagine it being used to check if a pointer is valid.
This is very very bad. Like, seriously bug-bug-buggy bad.

Sooner or later a memory area that was freed will be allocated for something else, and the pointer will look valid even though it's pointing to something else. So even if in your program *Ptr.MyStruct only is set to point to memory areas that resemble MyStruct, you could end up accessing a NotMyStruct area by checking if the memory pointer is valid.

Always use program flow or null pointers to know what is valid and what is not.
freak
PureBasic Team
PureBasic Team
Posts: 5940
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Post by freak »

> Although the "(SIZE_T) -1" is a bit confusing I assume this means it returns -1 on failure or does it mean ($FFFFFFFF)-1 ?

The (SIZE_T) is just a type cast. So it is -1 interpreted as a variable of type SIZE_T (still -1 in the PB world)

MemorySize() is a direct wrapper to HeapSize(), so it is the api command actually that crashes, not the PB part. Try:

Code: Select all

Debug HeapSize_(GetProcessHeap_(), 0, 123)
So it is no use for validation either.

The only way to implement this is if PB keeps a list of all allocated memory blocks,
i think this is a bit overkill.

I also agree with Tronds opinion.
Having a memory pointer of which you do not know if it is valid or not is a bug in the program imho. This should not happen.
quidquid Latine dictum sit altum videtur
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Post by Rescator »

Good points all around.
Just looked for alternative systems. (malloc, calloc, mmap, etc)
And I stumbled over some notes on OpenBSD, it seems even they now prefer to actually have software "crash" instead (to help enforce better coding habits/more bug squashing).

Oh well. So I guess IsMemory() is a good idea that is also a bad idea. *laughs*

Feel free to lock this thread. (deleting it may cause the question/feature to be asked again as IsMemory is mentioned nowhere else in these forums)
freak
PureBasic Team
PureBasic Team
Posts: 5940
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Post by freak »

If you just need to know if accessing a pointer would result in a crash, you can have
a look at the IsBadReadPtr_() and IsBadWritePtr_() API.

It only tells you if you can read or write at the memory location, not if and how it was allocated.
It may still be usefull in some cases.
(The PB debugger uses it to avoid a crash if you enter wrong numbers in the MemoryViewer for example.)
quidquid Latine dictum sit altum videtur
User avatar
Rescator
Addict
Addict
Posts: 1769
Joined: Sat Feb 19, 2005 5:05 pm
Location: Norway

Post by Rescator »

A cool, didn't know that... (I wonder how many hook coders remember to use those two? heh)
Konne
Enthusiast
Enthusiast
Posts: 434
Joined: Thu May 12, 2005 9:15 pm

Post by Konne »

Trond wrote:IsMemory() should not be implemented. There's probably other uses for it (or?), but I imagine it being used to check if a pointer is valid.
This is very very bad. Like, seriously bug-bug-buggy bad.

Sooner or later a memory area that was freed will be allocated for something else, and the pointer will look valid even though it's pointing to something else. So even if in your program *Ptr.MyStruct only is set to point to memory areas that resemble MyStruct, you could end up accessing a NotMyStruct area by checking if the memory pointer is valid.

Always use program flow or null pointers to know what is valid and what is not.
But that's the same with IsWindow/Gadget/Image etc.
Apart from that Mrs Lincoln, how was the show?
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

But that's the same with IsWindow/Gadget/Image etc.
Not quite as you can run into timing issues using callbacks where the order and timing of create/destroy for windows and gadgets can cause your code to try to work with a non-valid object. I often use If IsGadget() in my callbacks before affecting code to them and consider it a good coding practice. Perhaps I'm being too careful, but I don't think so. Images are another matter altogether as you must always be able to verify the successful loading/catching of images before trying to work with them. You can't just call LoadImage() and assume it's there and valid.
Konne
Enthusiast
Enthusiast
Posts: 434
Joined: Thu May 12, 2005 9:15 pm

Post by Konne »

MSDN Quote:
Remarks

A thread should not use IsWindow for a window that it did not create because the window could be destroyed after this function was called. Further, because window handles are recycled the handle could even point to a different window.
Apart from that Mrs Lincoln, how was the show?
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

Konne wrote:But that's the same with IsWindow/Gadget/Image etc.
Not really. Let's say you have a function that accepts an image. If you check the value with IsImage() you can be sure you've got a valid image.

Now let's say you write a function that accepts a pointer to MyStruct (80 bytes). You check the pointer with IsMemory() and feel safe, but you actually received a pointer to a NotMyStruct (4 bytes) and kaboom.
Konne
Enthusiast
Enthusiast
Posts: 434
Joined: Thu May 12, 2005 9:15 pm

Post by Konne »

But both things will lead to an error.
Apart from that Mrs Lincoln, how was the show?
Post Reply