I am creating scripting language. When I allocate thing ,it's allocate the thing and returns the address and then I do whatever with it and then delete it. I can't control the variables in it like creating struct in my lang (Struct with pointer and bool to check if pointer is pointing to valid data) and etc because it'll make my lang slower and bigger in the RAM.
For example: (My scripting language is easily to understood. I doubt you'll not understand this ,but I'll put some comments in it anyway)
MyStruct = { //Function. For create object with it use 'new' before it.
TestAliveVar=0
}
Func = { //I'll explain what exactly this function does every place it runs.
if (!exists(arg0)) //C++: ???
exit;
arg0.TestAliveVar=1
println "Still alive!";
}
var MyVar=new MyStruct(); //Returns address of the new object in the heap
//and runs on it the `MyStruct` function.
Func(MyVar); //Sets his 'TestAliveVar' to 1
//and prints 'Still Alive!' with new line
delete(MyVar); //C++: free(MyVar);
Func(MyVar); //Does nothing
The question is how to create the function exists
you saw in this code.
BTW I can run C++ codes in this lang.
One thing you could do is use your own allocator, in which you can allocate all your objects. Your
exists
function would simply query the allocator to see if the object is still allocated. Yo could use something similar to SMR to make sure your reference doesn't point to something else while still in use...The simplest solution is to use a map. The map should be indexed by a pointer to the object, likely as a
void *
. The contents of the map item should be the type of object created.Any time a script creates an object, add an entry to the map. Any time a script deletes an object, remove the map entry. When a script accesses an object, find the pointer in the map, thus confirming both that it exists and that the type is correct.
This valid check checked in windows only (VS),here is the function:
Usage:
Output:
Function's explanation: (What it does)
The functions check before the real checking ,if the address is valid\start point to memory. After that he checks if this process can reach this memory's prefix (If caught exception if can't) and the last checking is checking what the prefix of this memory if deleted at any mode. (Debugging\Without Debug Mode\Release Mode) If the function passed all of those checks ,it returns true.
This is a really bad idea. Whether a pointer is safe to use is based on more than just the value of the pointer, it's based on the entire history of the pointer. For instance, let's say that you allocate some memory, then deallocate it but you keep the pointer to it. This pointer is now invalid. Now something else gets allocated to the memory where the previous pointer is. Now if you try to detect if the old pointer is valid, it appears that it is, because the memory it points to is allocated, but if you try to use it, you get undefined behavior. If you read from it, you'll get garbage. If you try to write to it you'll probably corrupt the heap.
If all you want to do is detect is whether your process can access the memory that the pointer points to, that is possible but not portable, and definitely not a good idea (it will also be very slow). You basically have try to read from or write to it, and then catch the OS exception or signal that results. As I said, even this is a really bad idea. All it tells you is whether the OS will kill your process if you try to access it; not whether it's actually safe to use.
For more on why this is a bad idea, check out these blog posts from Raymond Chen, who works on some low-level stuff Windows stuff:
IsBadXxxPtr should really be called CrashProgramRandomly
There's no point improving the implementation of a bad idea
Detecting whether memory no longer is alive could be done e.g. by maintaining a set of known dead pointer. Any pointer you create gets added to an alive set, and when you delete the object you move the pointer to the dead set.
The really tricky part will be reusing memory. What do you do when you want to reuse the same address for a different object? You can't tell by looking at the pointer, because the pointers look the same. So unless you never want to reuse memory, you'll have to change your requirements.
You can use
shared_ptr<>
to hold your pointer, and useweak_ptr<>
to pass your pointer around to consumers of the object. Youdelete
the object by destroying theshared_ptr<>
object, and then all theweak_ptr<>
s will become expired.So, your
exists
check would be to check if theweak_ptr<>
is expired or not.To make the usage of the construct a little more concrete:
If the script is to operate in a multi-threaded environment, then the
weak_ptr<>
state is a critical section.