www.digitalmars.com         C & C++   DMDScript  

D - A pointer validation function ?

reply pontus <popi5501 student.uu.se> writes:
SGVsbG8NCg0KSSd2ZSBiZWVuIHBvbmRlcmluZyBvbiB0aGUgdmFsaWRhdGlvbiBvZiBwb2lu
dGVycywgYXMgd2UgYWxsIGhhdmUgZG9uZQ0KaXQgaXMgZWFzeSB0byBmb2xsb3cgYW4gcG9p
bnRlciBvdXRzaWRlIG9mIGFuIGFsbG9jYXRlZCBzZWdtZW50LA0KcmVzdWx0aW5nIGluIGEg
c2VnZmF1bHQuIFNvIEkgdGhvdWdodCwgc2luY2UgdGhlIE9TIGhhdmUgYWxsIHRoaXMgbmlj
ZQ0KaW5mb3JtYXRpb24gYWJvdXQgbWVtb3J5LCBpcyB0aGVyZSBhIHdheSBpdCBjYW4gc2hh
cmUgaXQgd2l0aCB0aGUNCnByb2dyYW1tZXI/IFdoYXQgSSdtIHJlYWxseSBsb29raW5nIGZv
ciBpcyBhIGZ1bmN0aW9uIHRvDQoidmFsaWRhdGUiIHBvaW50ZXJzLCBhIHN5c3RlbWNhbGwg
d2hlcmUgeW91IGFzayB0aGUgT1MgaWYgYSBwb2ludGVyIGlzDQppbiB0aGUgcHJvY2VzcyBh
ZHJlc3Mgc3BhY2UuIGxpa2UgdGhpczoNCg0KY2hhciAqbGV0dGVyczsNCmludCBvZmZzZXQg
PSBbYmlnIGFuZCBuYXN0eSBvZmZzZXQgY2FsY3VsYXRpb25zXTsNCg0KaWYodmFsaWQobGV0
dGVycyArIG9mZnNldCkgPT0gVHJ1ZSkNCnsNCiAgICAgIHByaW50ZigiJXNcbiIsIGxldHRl
cnNbb2Zmc2V0XSk7DQp9ZWxzZXsNCiAgICBwcmludGYoIlRyeWluZyB0byBhZHJlc3MgbGV0
dGVyIG91dHNpZGUgb2Ygc3RyaW5nXG4iKTsNCiAgICBleGl0KDApOw0KfQ0KDQpPZiBjb3Vy
c2UgYW55IHVzZSBvZiBzdWNoIGFuIGFkcmVzcyBpcyBhIGJ1ZyBhbmQgc2hvdWxkIGJlIGNv
cnJlY3RlZCBpbg0KYSByZWxlYXNlLCBidXQgYnVncyBzbGlwIHRocm91Z2guDQoNCkNhbiB0
aGlzIGJlIGRvbmUgd2l0aCB0aGUgYWlkIG9mIG1vc3QgT1MncyB0b2RheSwgb3IgY291bGQg
b25lIHdyYXAgdGhlDQpvcyBpbiBhIG1lbW9yeWhhbmRsZXIgd2hpY2gga25vd3MgdGhlc2Ug
dGhpbmdzLCB0aGUgRCBydW50aW1lIGZvcg0KaW5zdGFuY2UuDQpJZiBpdCBpcyBwb3NzaWJs
ZSBpdCB3b3VsZCByZXBsYWNlIHRoZSBsZXNzIGFjdXJhdGUgdGVzdCAocG9pbnRlcg0KPT0g
TlVMTCkuDQoNCkFsc28gdGhlIGZ1bmN0aW9uIGNvdWxkIHJldHVybiBhIGxvdCBvZiBuaWNl
IGluZm9ybWF0aW9uIGFib3V0IHRoZQ0Kc2VnbWVudCB0aGUgcG9pbnRlciBpcyBpbnNpZGUg
KGlmIGFueSksIGxpa2Ugc2l6ZSBhbmQgYm91bmRhcmllcy4NCg0KL1BvbnR1cw0K
Oct 07 2001
next sibling parent Axel Kittenberger <axel dtone.org> writes:
 I've been pondering on the validation of pointers, as we all have done
 it is easy to follow an pointer outside of an allocated segment,
 resulting in a segfault. So I thought, since the OS have all this nice
 information about memory, is there a way it can share it with the
 programmer? 
You can easily catch the SEGV signal if you want your application to behave differently than standard. (terminate). Termination on segfault is the default behavior since it make most times simply most sense. However if you want you can catch a SIGSEGV yourself, and then either do a backtrace yourself (the glibc has an undocumented backtrace() function, at least it's not in the man pages, and there is even one that evaluates symbolic references if you've compiled with debug info), or let it do curious things like sending an email to the admin until the worst behaviour ignore it, `man sigaction` for further stuff to that... - Axel
Oct 07 2001
prev sibling next sibling parent a <a b.c> writes:
pontus wrote:
 
 Hello
 
 I've been pondering on the validation of pointers, as we all have done
 it is easy to follow an pointer outside of an allocated segment,
 resulting in a segfault. So I thought, since the OS have all this nice
 information about memory, is there a way it can share it with the
 programmer? What I'm really looking for is a function to
 "validate" pointers, a systemcall where you ask the OS if a pointer is
 in the process adress space. like this:
 
 char *letters;
 int offset = [big and nasty offset calculations];
 
 if(valid(letters + offset) == True)
 {
       printf("%s\n", letters[offset]);
 }else{
     printf("Trying to adress letter outside of string\n");
     exit(0);
 }
 
 Of course any use of such an adress is a bug and should be corrected in
 a release, but bugs slip through.
I guess it might be handy, but I'd be afraid of the laziness it might encourage. I've always been of the opinion that using a pointer in a context that the programmer cannot be certain of it validity is an error. Of course this presumes that client code obeys preconditions and that functions that are supposed to return a pointer have a mechanism to say it failed to create the pointer (like returning null or throwing). I guess my biggest beef is that it might be a valid pointer in the sense that it points to your memory. It still might be read only memory when you plan to write. It may just be a bad pointer who is still in you address space. This routine might let you prevent seg fault, but even if it say the pointer is safe, it still may be an error. I don't see it providing any useful function except maybe for a memory manager. I'd almost rather have something to segfault me when I use a bad pointer that is still in my memory, but alas, I wouldn't trust the compiler to decide what is bad in many cases. For me, I guess GC is the best compromise. It would be nice to know if I had the last reference to an object, so I could verify that I don't have a memory leak. How unreasonable/dangerous do you think it would be to had GC store a reference count accurate as of the last sweep for each object? I guess the lack of instantaneous accuracy would make it useless in most cases. Dan
Oct 07 2001
prev sibling parent reply Russell Borogove <kaleja estarcion.com> writes:
pontus wrote:
 I've been pondering on the validation of pointers, as we all have done
 it is easy to follow an pointer outside of an allocated segment,
 resulting in a segfault. So I thought, since the OS have all this nice
 information about memory, is there a way it can share it with the
 programmer? What I'm really looking for is a function to
 "validate" pointers, a systemcall where you ask the OS if a pointer is
 in the process adress space. like this:
I agree with Axel's argument that if you can't use a pointer with confidence, you shouldn't use it at all, but there are exceptional cases (like if you're writing a library and don't really trust the library user). However, for such cases, the Win32 API provides the functions: IsBadCodePtr() IsBadStringPtr() IsBadReadPtr() IsBadWritePtr() If your runtime system maps invalid pointer accesses onto C++ exceptions, you can also do something like this: // reinterpret_cast your pointer to char*, then call this bool IsPointerValid( char* ptr ) { char c; try { c = *ptr; return true; // access succeeded, pointer is valid } catch { return false; // access threw an exception, pointer is invalid } } Unfortunately, these only tells you if the memory is accessible, not if it was what you really wanted to access. It's always a good idea to strive to reduce your reliance on pointers. Personally, I've found that creating a C++ "smart array" template class which does bounds checks in debug builds can catch a huge number of bugs, which frequently won't be caught immediately by the pointer checks above, because the block of memory one element past the end of any given array is usually accessible. -RB
Oct 08 2001
next sibling parent Russell Borogove <kaleja estarcion.com> writes:
Excuse my self-followup.

Russell Borogove wrote:
 I agree with Axel's argument...
...but meant "Dan", not "Axel". Sorry. -RB
Oct 08 2001
prev sibling next sibling parent reply "Walter" <walter digitalmars.com> writes:
"Russell Borogove" <kaleja estarcion.com> wrote in message
news:3BC2156A.90728BC7 estarcion.com...
 It's always a good idea to strive to reduce your reliance on
 pointers. Personally, I've found that creating a C++ "smart array"
 template class which does bounds checks in debug builds can
 catch a huge number of bugs, which frequently won't be caught
 immediately by the pointer checks above, because the block of
 memory one element past the end of any given array is usually
 accessible.
One of the ways D improves program reliability is eliminating much of the need for pointers via: 1) function inout and out parameters 2) improved arrays 3) all class objects are by reference
Oct 08 2001
parent reply Russell Borogove <kaleja estarcion.com> writes:
Walter wrote:
 
 "Russell Borogove" <kaleja estarcion.com> wrote in message
 news:3BC2156A.90728BC7 estarcion.com...
 It's always a good idea to strive to reduce your reliance on
 pointers. [...]
One of the ways D improves program reliability is eliminating much of the need for pointers via: 1) function inout and out parameters 2) improved arrays 3) all class objects are by reference
Yes. You can of course do this in C++, with pass-by-reference parameters, smart array classes, etc. C++ is more "pro-choice" than D in this matter, complete with the applicability of the "respect the right [to pointer use], reduce the need" slogan. :) (Please, please, please don't try to take this analogy too far.) -RB
Oct 08 2001
parent "Walter" <walter digitalmars.com> writes:
Russell Borogove wrote in message <3BC242DE.593399BD estarcion.com>...
Walter wrote:
 "Russell Borogove" <kaleja estarcion.com> wrote in message
 news:3BC2156A.90728BC7 estarcion.com...
 It's always a good idea to strive to reduce your reliance on
 pointers. [...]
One of the ways D improves program reliability is eliminating much of the need for pointers via: 1) function inout and out parameters 2) improved arrays 3) all class objects are by reference
Yes. You can of course do this in C++, with pass-by-reference parameters, smart array classes, etc. C++ is more "pro-choice" than D in this matter, complete with the applicability of the "respect the right [to pointer use], reduce the need" slogan. :)
You can do it all in assembler, too <g>.
Oct 08 2001
prev sibling parent Pontus Pihlgren <popi5501 student.uu.se> writes:
Russell Borogove wrote:
 
 pontus wrote:
 I've been pondering on the validation of pointers, as we all have done
 it is easy to follow an pointer outside of an allocated segment,
 resulting in a segfault. So I thought, since the OS have all this nice
 information about memory, is there a way it can share it with the
 programmer? What I'm really looking for is a function to
 "validate" pointers, a systemcall where you ask the OS if a pointer is
 in the process adress space. like this:
I agree with Axel's argument that if you can't use a pointer with confidence, you shouldn't use it at all, but there are exceptional
Russell Borogove wrote:
 bool IsPointerValid( char* ptr )
 {
 .....
 }
I supose that this is what i was looking for really.
 memory one element past the end of any given array is usually
 accessible.
The bounds checking is the way to go. But I thought it might be intresting to know more (can't think of an exact aplication...) like the actuall size of the segment you allocated. /Points
Oct 09 2001