469,921 Members | 2,176 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,921 developers. It's quick & easy.

checking if pointer is NULL allowed?

atv
Hi,
Just to check, if i set a pointer explicitly to NULL, i'm not allowed
to dereference it? Why is that, it's not
like it's pointing to any garbage right? Why else set it to NULL. I can
remember some instances where
i did just that and printf reported something like : (null).

I'm asking because i read somewhere that it is not valid. I thought it
simply wasn't valid to dereference
a pointer who is _not_ set to point to anything.

But i can check if it is NULL or not right ? ( i hope ) :-)

Rgds,
-alef

Jan 24 '07 #1
51 3727
In article <45*********************@news.xs4all.nl>,
atv <al**@xs4all.nlwrote:
>Just to check, if i set a pointer explicitly to NULL, i'm not allowed
to dereference it?
Right.
>Why is that, it's not
like it's pointing to any garbage right?
It isn't pointing to anything, so I guess from that point of view
it isn't pointing to any garbage. ;-)
>Why else set it to NULL. I can
remember some instances where
i did just that and printf reported something like : (null).
>I'm asking because i read somewhere that it is not valid. I thought it
simply wasn't valid to dereference
a pointer who is _not_ set to point to anything.
But a NULL pointer -has- been set not to point to anything. The NULL
pointer is -defined- as not pointing to any valid object. What would
it mean to dereference it? The situation is philosophically similar
to dereferencing a void* pointer -- there is no "is" there!
--
"No one has the right to destroy another person's belief by
demanding empirical evidence." -- Ann Landers
Jan 24 '07 #2
atv wrote:
Hi,
Just to check, if i set a pointer explicitly to NULL, i'm not allowed
to dereference it?
You _can_, but the behaviour is undefined, since in C, a NULL pointer
is guaranteed to not point to any valid object.
Why is that, it's not
like it's pointing to any garbage right? Why else set it to NULL.
Setting an uninitialised pointer to NULL is a good practise. Also some
functions require a null pointer. Many programming constructs require a
null pointer as a sentinel value. Many functions return a null pointer
as an indication of failure.

<snip>
I'm asking because i read somewhere that it is not valid. I thought it
simply wasn't valid to dereference
a pointer who is _not_ set to point to anything.
Yes.
But i can check if it is NULL or not right ? ( i hope ) :-)
Yes, you can.

Jan 24 '07 #3
Well, if it is not pointing to anything anyway, couldn't my compiler
just printf out "null". And i swear i thought i have seen this.
and if i can check for it to be NULL (i'm assuming that's why you set
it to NULL in the first place, like you said, good practice) how does
it do this. Does it keep track of memory assignments?

Jan 24 '07 #4
Al*******@gmail.com wrote:
Well, if it is not pointing to anything anyway, couldn't my compiler
just printf out "null". And i swear i thought i have seen this.
Yes, some libc implemetations (that's where printf() is located)
check if a pointer passed to printf() is NULL and then print out
"(null)" instead of crashing. But don't rely on that.
and if i can check for it to be NULL (i'm assuming that's why you set
it to NULL in the first place, like you said, good practice) how does
it do this. Does it keep track of memory assignments?
Setting uninitialized pointers (or pointers on which you have called
free()) to NULL is good for _you_ since then can check if a pointer
is valid or not. When you e.g. have

char *x = malloc( 10 );
if ( x == NULL ) {
exit( 0 );
}
free(x);

you can't see by simply looking at the value of 'x' if it's a pointer
that points to any memory you own (actually, just checking the value
of a pointer after a call of free() is forbidden). But if you always
set such pointer to NULL then _you_ can test if it's a valid pointer
or not and _you_ can thus avoid using bad pointers (moreover, if the
pointer ist invalid but not NULL and accidentaly points to some memory
you can access it might look as dereferencing it works as expected
while in reality there's a big fat bug in your code).

Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
Jan 24 '07 #5
that's what i suspected and wanted to hear, thanks :-)

On Jan 24, 8:05 pm, j...@toerring.de (Jens Thoms Toerring) wrote:
Alef.V...@gmail.com wrote:
Well, if it is not pointing to anything anyway, couldn't my compiler
just printf out "null". And i swear i thought i have seen this.Yes, some libc implemetations (that's where printf() is located)
check if a pointer passed to printf() is NULL and then print out
"(null)" instead of crashing. But don't rely on that.
and if i can check for it to be NULL (i'm assuming that's why you set
it to NULL in the first place, like you said, good practice) how does
it do this. Does it keep track of memory assignments?Setting uninitialized pointers (or pointers on which you have called
free()) to NULL is good for _you_ since then can check if a pointer
is valid or not. When you e.g. have

char *x = malloc( 10 );
if ( x == NULL ) {
exit( 0 );
}
free(x);

you can't see by simply looking at the value of 'x' if it's a pointer
that points to any memory you own (actually, just checking the value
of a pointer after a call of free() is forbidden). But if you always
set such pointer to NULL then _you_ can test if it's a valid pointer
or not and _you_ can thus avoid using bad pointers (moreover, if the
pointer ist invalid but not NULL and accidentaly points to some memory
you can access it might look as dereferencing it works as expected
while in reality there's a big fat bug in your code).

Regards, Jens
--
\ Jens Thoms Toerring ___ j...@toerring.de
\__________________________ http://toerring.de
Jan 24 '07 #6
In article <45*********************@news.xs4all.nl>,
atv <al**@xs4all.nlwrote:
>Just to check, if i set a pointer explicitly to NULL, i'm not allowed
to dereference it?
[...]
>But i can check if it is NULL or not right ? ( i hope ) :-)
Perhaps you misunderstand "dereference"? You're allowed to test the
pointer itself:

if(p == null) /* good */

but not "follow" it:

if(*p == 'a') /* bad */

printf()s that print "(null)" for NULL pointers are doing something
like:

if(p == NULL)
puts("(null)");
else
..whatever..;

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Jan 24 '07 #7
Al*******@gmail.com wrote:
that's what i suspected and wanted to hear, thanks :-)
Please don't top-post. Your replies belong following or interspersed
with properly trimmed quotes. See the majority of other posts in the
newsgroup, or:
<http://www.caliburn.nl/topposting.html>
Jan 24 '07 #8
Al*******@gmail.com wrote:
Well, if it is not pointing to anything anyway, couldn't my compiler
just printf out "null". And i swear i thought i have seen this.
It's undefined behavior. There IS NO DEFINED BEHAVIOR for undefined
behavior. Say that over and over until you get it. That means that if
your implentation wants to crash it can crash. There is no defined
behavior for undefined behavior. If your implementation wants to print
(null), it can. There is no defined behavior for undefined behavior.

PS:

There is no defined behavior for undefined behavior.

Brian
Jan 24 '07 #9
Al*******@gmail.com writes:
Well, if it is not pointing to anything anyway, couldn't my compiler
just printf out "null". And i swear i thought i have seen this.
Are you confusing dereferencing an invalid pointer with passing a
null pointer to printf in place of a pointer argument? Both are
undefined behavior. The former is usually difficult or expensive
for an implementation to detect, whereas the latter is handled
gracefully by better-quality C libraries (which often do print
"null" or "(null)").
--
"In My Egotistical Opinion, most people's C programs should be indented six
feet downward and covered with dirt." -- Blair P. Houghton
Jan 24 '07 #10
Ben Pfaff wrote:
Al*******@gmail.com writes:

>>Well, if it is not pointing to anything anyway, couldn't my compiler
just printf out "null". And i swear i thought i have seen this.


Are you confusing dereferencing an invalid pointer with passing a
null pointer to printf in place of a pointer argument? Both are
undefined behavior. The former is usually difficult or expensive
for an implementation to detect, whereas the latter is handled
gracefully by better-quality C libraries (which often do print
"null" or "(null)").
That depend on one's idea of graceful. Passing a null pointer as a
parameter to printf is never, a good thing to do.

--
Ian Collins.
Jan 24 '07 #11
Ian Collins wrote:
Ben Pfaff wrote:
Al*******@gmail.com writes:

>Well, if it is not pointing to anything anyway, couldn't my compiler
just printf out "null". And i swear i thought i have seen this.

Are you confusing dereferencing an invalid pointer with passing a
null pointer to printf in place of a pointer argument? Both are
undefined behavior. The former is usually difficult or expensive
for an implementation to detect, whereas the latter is handled
gracefully by better-quality C libraries (which often do print
"null" or "(null)").

That depend on one's idea of graceful. Passing a null pointer as a
parameter to printf is never, a good thing to do.
Never say never :) There's nothing wrong with printf("%p", (void *) 0);

Jan 25 '07 #12
in 716374 20070124 230752 Ben Pfaff <bl*@cs.stanford.eduwrote:
>Al*******@gmail.com writes:
>Well, if it is not pointing to anything anyway, couldn't my compiler
just printf out "null". And i swear i thought i have seen this.

Are you confusing dereferencing an invalid pointer with passing a
null pointer to printf in place of a pointer argument? Both are
undefined behavior. The former is usually difficult or expensive
for an implementation to detect, whereas the latter is handled
gracefully by better-quality C libraries (which often do print
"null" or "(null)").
Surely all the OP needed to know is that inspecting the value of a pointer
does not constitute "dereferencing" it?
Jan 25 '07 #13
On 24 Jan 2007 23:07:27 -0800, "Harald van D?k" <tr*****@gmail.com>
wrote:
>Ian Collins wrote:
>Ben Pfaff wrote:
Al*******@gmail.com writes:
Well, if it is not pointing to anything anyway, couldn't my compiler
just printf out "null". And i swear i thought i have seen this.
Are you confusing dereferencing an invalid pointer with passing a
null pointer to printf in place of a pointer argument? Both are
undefined behavior. The former is usually difficult or expensive
for an implementation to detect, whereas the latter is handled
gracefully by better-quality C libraries (which often do print
"null" or "(null)").

That depend on one's idea of graceful. Passing a null pointer as a
parameter to printf is never, a good thing to do.

Never say never :) There's nothing wrong with printf("%p", (void *) 0);
And oddly enough, there may be something wrong with the following,
understandble, mistake:

/*let's print the value of the NULL pointer*/
printf("%p\n", NULL);

--
jay
Jan 25 '07 #14
Ben Pfaff wrote:
Alef.V...@gmail.com writes:
>>Well, if it is not pointing to anything anyway, couldn't my compiler
just printf out "null". And i swear i thought i have seen this.
Are you confusing dereferencing an invalid pointer with passing a
null pointer to printf in place of a pointer argument?
I'm not quite sure what you mean here. I just wanted to know why i
sometimes noticed that printf printed out a nice "null" when i gave it
a pointer i explicitly set to NULL. I'm not talking about 'bad'
pointers here. But now i have my answer, the better libc libraries do
print this out. Thanks everyone.

Surely all the OP needed to know is that inspecting the value of a
pointer
does not constitute "dereferencing" it?

No. I know that :-)

And oddly enough, there may be something wrong with the following,
understandble, mistake:
/*let's print the value of the NULL pointer*/
printf("%p\n", NULL);
--
jay

Would this not print out something akin to 0x0?

Jan 25 '07 #15
Ben Pfaff wrote:
Al*******@gmail.com writes:
>Well, if it is not pointing to anything anyway, couldn't my compiler
just printf out "null". And i swear i thought i have seen this.

Are you confusing dereferencing an invalid pointer with passing a
null pointer to printf in place of a pointer argument? Both are
undefined behavior. The former is usually difficult or expensive
for an implementation to detect, whereas the latter is handled
gracefully by better-quality C libraries (which often do print
"null" or "(null)").
It is common practice in many shops I've worked at to have a function or
macro used in debugging routines that can take a pointer and return the
pointer or "null", depending on if the pointer is valid to dereference
or not.
Jan 25 '07 #16
Clever Monkey <cl**************@hotmail.com.invalidwrites:
It is common practice in many shops I've worked at to have a function
or macro used in debugging routines that can take a pointer and return
the pointer or "null", depending on if the pointer is valid to
dereference or not.
What kind of code do you work on?
--
"To get the best out of this book, I strongly recommend that you read it."
--Richard Heathfield
Jan 25 '07 #17
Clever Monkey wrote:
Ben Pfaff wrote:
Al*******@gmail.com writes:
Well, if it is not pointing to anything anyway, couldn't my compiler
just printf out "null". And i swear i thought i have seen this.
Are you confusing dereferencing an invalid pointer with passing a
null pointer to printf in place of a pointer argument? Both are
undefined behavior. The former is usually difficult or expensive
for an implementation to detect, whereas the latter is handled
gracefully by better-quality C libraries (which often do print
"null" or "(null)").

It is common practice in many shops I've worked at to have a function or
macro used in debugging routines that can take a pointer and return the
pointer or "null", depending on if the pointer is valid to dereference
or not.
Maybe, but that's not possible in standard C.

Jan 25 '07 #18
Al*******@gmail.com writes:
Ben Pfaff wrote:
Alef.V...@gmail.com writes:
>Well, if it is not pointing to anything anyway, couldn't my compiler
just printf out "null". And i swear i thought i have seen this.
Are you confusing dereferencing an invalid pointer with passing a
null pointer to printf in place of a pointer argument?

I'm not quite sure what you mean here. I just wanted to know why i
sometimes noticed that printf printed out a nice "null" when i gave it
a pointer i explicitly set to NULL. I'm not talking about 'bad'
pointers here. But now i have my answer, the better libc libraries do
print this out. Thanks everyone.

Surely all the OP needed to know is that inspecting the value of a
pointer
does not constitute "dereferencing" it?

No. I know that :-)

And oddly enough, there may be something wrong with the following,
understandble, mistake:
/*let's print the value of the NULL pointer*/
printf("%p\n", NULL);
--
jay

Would this not print out something akin to 0x0?
It's very difficult to tell which parts of your followup are quoted
from previous articles, since you didn't use "" markers. You're
also missing some attribution lines, so it's hard to tell who you're
quoting. Google Groups does these for you automatically, so I'm not
sure what went wrong here.

jay wrote the last bit:
| And oddly enough, there may be something wrong with the following,
| understandble, mistake:
| /*let's print the value of the NULL pointer*/
| printf("%p\n", NULL);

One legal definition for the NULL macro is just 0, which is a null
pointer constant, but is only treated as a pointer in the right
context. Since printf is a variadic function (it takes a variable
number and type(s) of arguments), the compiler doesn't know that that
argument is supposed to be a pointer; it just passes a value of type
int with value 0, which may or may not look like a null pointer by the
time printf sees it.

The correct way to print the value of a null pointer is:

printf("%p\n", (void*)NULL);

The output is implementation-defined.

Section 5 of the comp.lang.c FAQ, <http://www.c-faq.com/has a lot
more information on this.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 25 '07 #19
On Jan 25, 9:23 am, "santosh" <santosh....@gmail.comwrote:
Clever Monkey wrote:
It is common practice in many shops I've worked at to have a function or
macro used in debugging routines that can take a pointer and return the
pointer or "null", depending on if the pointer is valid to dereference
or not.

Maybe, but that's not possible in standard C.
why not?

Jan 25 '07 #20
In article <11**********************@a75g2000cwd.googlegroups .com>,
tedu <tu@zeitbombe.orgwrote:
It is common practice in many shops I've worked at to have a function or
macro used in debugging routines that can take a pointer and return the
pointer or "null", depending on if the pointer is valid to dereference
or not.
>Maybe, but that's not possible in standard C.
>why not?
You can tell whether it's null (which I suspect is what was meant) but
you can't check that it's "valid to dereference" - it might be a
free()ed pointer for example.

-- Richard

--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Jan 26 '07 #21
tedu wrote:
On Jan 25, 9:23 am, "santosh" <santosh....@gmail.comwrote:
>Clever Monkey wrote:
It is common practice in many shops I've worked at to have a function or
macro used in debugging routines that can take a pointer and return the
pointer or "null", depending on if the pointer is valid to dereference
or not.

Maybe, but that's not possible in standard C.

why not?
There's no way to find out if "the pointer is valid to dereference
or not".

However you try and construct one, you will find undefined
behaviour lying in wait.

(A /specific implementation/ might offer such a function, although
I can't see it being both reliable and cheap.)

--
Chris "electric hedgehog" Dollin
"Our future looks secure, but it's all out of our hands"
- Magenta, /Man and Machine/

Jan 26 '07 #22
Chris Dollin said:
tedu wrote:
>On Jan 25, 9:23 am, "santosh" <santosh....@gmail.comwrote:
>>Clever Monkey wrote:
It is common practice in many shops I've worked at to have a function
or macro used in debugging routines that can take a pointer and return
the pointer or "null", depending on if the pointer is valid to
dereference or not.

Maybe, but that's not possible in standard C.

why not?

There's no way to find out if "the pointer is valid to dereference
or not".
Well, you know that it isn't valid to deref if it's NULL. So the trick here
is to ensure that all your pointers are *either* valid *or* NULL,
throughout your code. Change the paradigm. Instead of thinking "how do I
detect whether I've screwed up" (which is generally a good thing to think,
but in this case turns out to be impractical in portable code), think "what
coding habits can I adopt that minimise the risk of screwing up in the
first place?"

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Jan 26 '07 #23
Keith Thompson wrote:
Al*******@gmail.com writes:
Ben Pfaff wrote:
Alef.V...@gmail.com writes:
>>Well, if it is not pointing to anything anyway, couldn't my compiler
>>just printf out "null". And i swear i thought i have seen this.
Are you confusing dereferencing an invalid pointer with passing a
null pointer to printf in place of a pointer argument?
I'm not quite sure what you mean here. I just wanted to know why i
sometimes noticed that printf printed out a nice "null" when i gave it
a pointer i explicitly set to NULL. I'm not talking about 'bad'
pointers here. But now i have my answer, the better libc libraries do
print this out. Thanks everyone.

Surely all the OP needed to know is that inspecting the value of a
pointer
does not constitute "dereferencing" it?

No. I know that :-)

And oddly enough, there may be something wrong with the following,
understandble, mistake:
/*let's print the value of the NULL pointer*/
printf("%p\n", NULL);
--
jay

Would this not print out something akin to 0x0?

It's very difficult to tell which parts of your followup are quoted
from previous articles, since you didn't use "" markers. You're
also missing some attribution lines, so it's hard to tell who you're
quoting. Google Groups does these for you automatically, so I'm not
sure what went wrong here.
He replied to two messages with one. Google quoted Ben Pfaff's message,
with an attribution line, and "" markers. He added jaysome's message,
with a simple copy and paste.
jay wrote the last bit:
| And oddly enough, there may be something wrong with the following,
| understandble, mistake:
| /*let's print the value of the NULL pointer*/
| printf("%p\n", NULL);

One legal definition for the NULL macro is just 0, which is a null
pointer constant, but is only treated as a pointer in the right
context. Since printf is a variadic function (it takes a variable
number and type(s) of arguments), the compiler doesn't know that that
argument is supposed to be a pointer; it just passes a value of type
int with value 0, which may or may not look like a null pointer by the
time printf sees it.

The correct way to print the value of a null pointer is:

printf("%p\n", (void*)NULL);

The output is implementation-defined.
I would (and did) use (void *) 0. (void *) NULL is valid in this
context, but not in some others where (void *) 0 is, because it is not
necessarily a null pointer constant. All it is sure to be is a constant
null pointer.
Section 5 of the comp.lang.c FAQ, <http://www.c-faq.com/has a lot
more information on this.
Jan 26 '07 #24
Richard Heathfield wrote:
Chris Dollin said:
tedu wrote:
On Jan 25, 9:23 am, "santosh" <santosh....@gmail.comwrote:
Clever Monkey wrote:
It is common practice in many shops I've worked at to have a function
or macro used in debugging routines that can take a pointer and return
the pointer or "null", depending on if the pointer is valid to
dereference or not.

Maybe, but that's not possible in standard C.

why not?
There's no way to find out if "the pointer is valid to dereference
or not".

Well, you know that it isn't valid to deref if it's NULL
and not one past the last element of an array.

Jan 26 '07 #25
On Fri, 26 Jan 2007 08:33:08 +0000, Richard Heathfield
<rj*@see.sig.invalidwrote:
>Chris Dollin said:
>tedu wrote:
>>On Jan 25, 9:23 am, "santosh" <santosh....@gmail.comwrote:
Clever Monkey wrote:
It is common practice in many shops I've worked at to have a function
or macro used in debugging routines that can take a pointer and return
the pointer or "null", depending on if the pointer is valid to
dereference or not.

Maybe, but that's not possible in standard C.

why not?

There's no way to find out if "the pointer is valid to dereference
or not".

Well, you know that it isn't valid to deref if it's NULL. So the trick here
is to ensure that all your pointers are *either* valid *or* NULL,
throughout your code. Change the paradigm. Instead of thinking "how do I
detect whether I've screwed up" (which is generally a good thing to think,
but in this case turns out to be impractical in portable code), think "what
coding habits can I adopt that minimise the risk of screwing up in the
first place?"
Yes.

And thinking about both gives you the best of said both worlds.
Everyone screws up--so every smart person, process and tool you can
throw at these two pillars of your paradigm is worth it, and arguably
even priceless.

Regards
--
jay
Jan 26 '07 #26
On Fri, 26 Jan 2007 08:25:36 +0000, Chris Dollin <ch**********@hp.com>
wrote:

[snip]
>(A /specific implementation/ might offer such a function, although
I can't see it being both reliable and cheap.)
It depends on your definitions of "reliable" and "cheap".

On one specific implementation I know of:

#include <stdio.h>
#include <time.h>
#include <windows.h>
#define NUM 0x4000
#define NUM_RUNS 10
int main(void)
{
unsigned nn;
clock_t c1, c2;
for ( nn = 0; nn < NUM_RUNS; nn++ )
{
int ii, num_bad = 0;
c1 = clock();
for ( ii = 0; ii < NUM; ii++ )
{
num_bad += IsBadReadPtr((void*)ii, 1) != 0;//lint !e514
}
c2 = clock();
printf("tested: 0x%04X; bad: 0x%04X\n", NUM, num_bad);
printf("%.1f microseconds per call\n",
(c2 - c1) / (double)CLOCKS_PER_SEC / NUM * 1e6);
}
return 0;
}

Output:

tested: 0x4000; bad: 0x4000
8.5 microseconds per call
tested: 0x4000; bad: 0x4000
9.5 microseconds per call
tested: 0x4000; bad: 0x4000
8.6 microseconds per call
tested: 0x4000; bad: 0x4000
8.6 microseconds per call
tested: 0x4000; bad: 0x4000
8.5 microseconds per call
tested: 0x4000; bad: 0x4000
8.6 microseconds per call
tested: 0x4000; bad: 0x4000
9.5 microseconds per call
tested: 0x4000; bad: 0x4000
8.6 microseconds per call
tested: 0x4000; bad: 0x4000
8.5 microseconds per call
tested: 0x4000; bad: 0x4000
8.6 microseconds per call
Press any key to continue

Regards
--
jay
Jan 26 '07 #27
jaysome wrote:
On Fri, 26 Jan 2007 08:25:36 +0000, Chris Dollin <ch**********@hp.com>
wrote:

[snip]
>>(A /specific implementation/ might offer such a function, although
I can't see it being both reliable and cheap.)

It depends on your definitions of "reliable" and "cheap".
Surely. I meant by "reliable" "gives the right answer so often it's
worth using" and by "cheap" "it's performance doesn't cripple the
application". Still room for manouever, of course.
>
On one specific implementation I know of:

#include <stdio.h>
#include <time.h>
#include <windows.h>
#define NUM 0x4000
#define NUM_RUNS 10
int main(void)
{
unsigned nn;
clock_t c1, c2;
for ( nn = 0; nn < NUM_RUNS; nn++ )
{
int ii, num_bad = 0;
c1 = clock();
for ( ii = 0; ii < NUM; ii++ )
{
num_bad += IsBadReadPtr((void*)ii, 1) != 0;//lint !e514
}
c2 = clock();
printf("tested: 0x%04X; bad: 0x%04X\n", NUM, num_bad);
printf("%.1f microseconds per call\n",
(c2 - c1) / (double)CLOCKS_PER_SEC / NUM * 1e6);
}
return 0;
}

Output:

tested: 0x4000; bad: 0x4000
8.5 microseconds per call
tested: 0x4000; bad: 0x4000
9.5 microseconds per call
tested: 0x4000; bad: 0x4000
8.6 microseconds per call
tested: 0x4000; bad: 0x4000
8.6 microseconds per call
tested: 0x4000; bad: 0x4000
8.5 microseconds per call
tested: 0x4000; bad: 0x4000
8.6 microseconds per call
tested: 0x4000; bad: 0x4000
9.5 microseconds per call
tested: 0x4000; bad: 0x4000
8.6 microseconds per call
tested: 0x4000; bad: 0x4000
8.5 microseconds per call
tested: 0x4000; bad: 0x4000
8.6 microseconds per call
Press any key to continue
8 microseconds per call I'd put in the non-cheap category, assuming
the machine is of the order of a GHz: it's taken about 8000 instructions
to do that test.

For reliability I'd want to check things like:

assertTrue( SIZE 0 );
char *spoo = malloc( SIZE );
assertTrue( canDereference( spoo ) );
assertFalse( canDereference( spoo + SIZE ) );
free( spoo );
assertFalse( canDereference( spoo ) );

and

int *broken( int arg ) { return &arg; }

assertFalse( canDereference( broken( 17 ) ) );

but it's possible I'm being too picky for the Clever Monkey's
context. (Mind you, I really do want to check that not only
is it legal to dereference something, but that it's mine to
dereference and not some random address taken at random out
of a random hat coloured a random shade of red.)

--
Chris "electric hedgehog" Dollin
Meaning precedes definition.

Jan 26 '07 #28
Chris Dollin wrote:
jaysome wrote:
>On Fri, 26 Jan 2007 08:25:36 +0000, Chris Dollin <ch**********@hp.com>
wrote:

[snip]
>>>(A /specific implementation/ might offer such a function, although
I can't see it being both reliable and cheap.)

It depends on your definitions of "reliable" and "cheap".

Surely. I meant by "reliable" "gives the right answer so often it's
worth using" and by "cheap" "it's performance doesn't cripple the
application". Still room for manouever, of course.
.... and not forgetting that the context described was for /debugging/,
where it's more like "right often enough to spot bugs" and "doesn't
make debugging ridiculously slow".

Richard H's approach of "program in such a way that you don't need
to ask those kinds of questions [1]" seems ... useful.

[1] "Hardly ever" [2]

[2] But maybe often enough that you can remember what to do when
you've made a really subtle mistake.

--
Chris "electric hedgehog" Dollin
A rock is not a fact. A rock is a rock.

Jan 26 '07 #29
Harald van Dijk wrote, On 26/01/07 08:35:
Keith Thompson wrote:
<snip>
>The correct way to print the value of a null pointer is:

printf("%p\n", (void*)NULL);

The output is implementation-defined.

I would (and did) use (void *) 0. (void *) NULL is valid in this
context, but not in some others where (void *) 0 is, because it is not
necessarily a null pointer constant. All it is sure to be is a constant
null pointer.
In what context would "(void *)NULL" be invalid but "(void *)0" valid? I
can't think of any since since "(void *)NULL" will expand to either
"(void *)constant-expression-evaluating-to-0" or "(void *)(void
*)constant-expression-evaluating-to-0" and the cast from void* to void*
does no harm. Perhaps you where thinking of NULL on its own is not valid
in all contexts where (void *)0 is?
--
Flash Gordon
Jan 26 '07 #30
Richard Tobin wrote:
In article <11**********************@a75g2000cwd.googlegroups .com>,
tedu <tu@zeitbombe.orgwrote:
>>>It is common practice in many shops I've worked at to have a function or
macro used in debugging routines that can take a pointer and return the
pointer or "null", depending on if the pointer is valid to dereference
or not.
>>Maybe, but that's not possible in standard C.
>why not?

You can tell whether it's null (which I suspect is what was meant) but
you can't check that it's "valid to dereference" - it might be a
free()ed pointer for example.
We check it for null, which is a valid enough check for a debug/logging
routine. If it has been freed and causes the debug to crash, then we
can consider this a "free" assert and can fix it, because we are
generally not interested in the pointer once it has been freed.

That is, in the context of a debug statement, a "valid pointer" is one
that is either null or can be dereferenced legally to pass to printf.
Jan 26 '07 #31
Ben Pfaff wrote:
Clever Monkey <cl**************@hotmail.com.invalidwrites:
>It is common practice in many shops I've worked at to have a function
or macro used in debugging routines that can take a pointer and return
the pointer or "null", depending on if the pointer is valid to
dereference or not.

What kind of code do you work on?
The code I am most familiar with where we have such debug routines is a
chunk of legacy code that does a fair amount of string manipulation on
items that are passed around in "instance" pointers that refer to files
and describe relationships to other files and pointers.

When I got here the debug routines were already in place. Basically we
have a debug module that we link in that has a run-time component. We
check for a few environment variables on startup, and based on that
enable 1-4 levels of debug() statements. If the variables are not set
the debug statements are turned into no-ops.

The debugging routines are implemented as varargs (I recall), so for
strings we know might be null we pass them through a "nulString()"
helper function that returns the pointer unmaligned, or the equivalent
replacement string that simply says "null" (or something).

For other issues, like pointers that might be freed before logging them,
this would be a bug in the code and a failure in the logger may as well
be caught ASAP.

It isn't perfect, and may in fact break some conventions or rules by
today's standards, but it was put in place literally decades ago.
Changing it now would introduce significant risk without giving us
something obvious in return. It is unlikely we are going to port this
library to any more platforms. It already runs nicely on a gaggle of
Unices and a long history of Windows stretching back to Win16. (Though
I'm sure it would break nicely on Win16 now).

Alas, the sun is sinking on this code as more and more is subsumed by
newer code written in Java.
Jan 26 '07 #32
Clever Monkey wrote:
Ben Pfaff wrote:
>Clever Monkey <cl**************@hotmail.com.invalidwrites:
>>It is common practice in many shops I've worked at to have a function
or macro used in debugging routines that can take a pointer and return
the pointer or "null", depending on if the pointer is valid to
dereference or not.

What kind of code do you work on?
The debugging routines are implemented as varargs (I recall), so for
strings we know might be null we pass them through a "nulString()"
helper function that returns the pointer unmaligned, or the equivalent
replacement string that simply says "null" (or something).
Ahhh. So what you mean is, a function that says:

return arg == null ? "null" : arg;

Yes, that's fine in standard C, but that's not what I read "valid to
dereference" as meaning.

--
Chris "electric hedgehog" Dollin
Meaning precedes definition.

Jan 26 '07 #33
Clever Monkey wrote:
Richard Tobin wrote:
In article <11**********************@a75g2000cwd.googlegroups .com>,
tedu <tu@zeitbombe.orgwrote:
>>It is common practice in many shops I've worked at to have a function or
macro used in debugging routines that can take a pointer and return the
pointer or "null", depending on if the pointer is valid to dereference
or not.
>Maybe, but that's not possible in standard C.
why not?
You can tell whether it's null (which I suspect is what was meant) but
you can't check that it's "valid to dereference" - it might be a
free()ed pointer for example.
We check it for null, which is a valid enough check for a debug/logging
routine. If it has been freed and causes the debug to crash, then we
can consider this a "free" assert and can fix it, because we are
generally not interested in the pointer once it has been freed.
So what is done with the pointers after they've been free()'ed?
That is, in the context of a debug statement, a "valid pointer" is one
that is either null or can be dereferenced legally to pass to printf.
So the check doesn't really verify that a non-null pointer can be
validly deferenced. That much can be done with standard C, and IMHO,
it's not very useful.

Jan 26 '07 #34
santosh wrote:
So the check doesn't really verify that a non-null pointer can be
validly deferenced. That much can be done with standard C, and IMHO,
it's not very useful.
It's useful for debug prints, which is what Clever Monkey said they
were used in. Myself, I'd likely have a cut-down version of (va)printf,
with %s doing an explicit check for null: then I don't have to remember
to call the replace-null-with-"null" function in calls.

--
Chris "electric hedgehog" Dollin
"Who are you? What do you want?" /Babylon 5/

Jan 26 '07 #35
>On Fri, 26 Jan 2007 08:25:36 +0000, Chris Dollin <ch**********@hp.com>
>wrote:
>>(A /specific implementation/ might offer such a function, although
I can't see it being both reliable and cheap.)
In article <8b********************************@4ax.com>
jaysome <ja*****@hotmail.comwrote:
>It depends on your definitions of "reliable" and "cheap".
Indeed. Particularly "reliable". :-)

[snippage]
num_bad += IsBadReadPtr((void*)ii, 1) != 0;//lint !e514
Before using IsBad{Read,Write}Ptr on Windows machines, see
<http://blogs.msdn.com/larryosterman/archive/2004/05/18/134471.aspx>.
The way IsBadReadPtr affects stack guard pages is particularly
tricky.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Jan 26 '07 #36
Chris Dollin wrote:
santosh wrote:
>So the check doesn't really verify that a non-null pointer can be
validly deferenced. That much can be done with standard C, and IMHO,
it's not very useful.

It's useful for debug prints, which is what Clever Monkey said they
were used in. Myself, I'd likely have a cut-down version of (va)printf,
with %s doing an explicit check for null: then I don't have to remember
to call the replace-null-with-"null" function in calls.
We've thought about replacing this some time ago, but this is seriously
legacy code. The debug stuff is never on anymore anyway, since it is
called via JNI now.
Jan 26 '07 #37
santosh wrote:
Clever Monkey wrote:
>Richard Tobin wrote:
>>In article <11**********************@a75g2000cwd.googlegroups .com>,
tedu <tu@zeitbombe.orgwrote:

>It is common practice in many shops I've worked at to have a function or
>macro used in debugging routines that can take a pointer and return the
>pointer or "null", depending on if the pointer is valid to dereference
>or not.
Maybe, but that's not possible in standard C.
why not?
You can tell whether it's null (which I suspect is what was meant) but
you can't check that it's "valid to dereference" - it might be a
free()ed pointer for example.
We check it for null, which is a valid enough check for a debug/logging
routine. If it has been freed and causes the debug to crash, then we
can consider this a "free" assert and can fix it, because we are
generally not interested in the pointer once it has been freed.

So what is done with the pointers after they've been free()'ed?
Er, nothing? I'm not sure what you mean. Whether something has been
freed are it has not. Generally, during the lifetime of this library,
things are freed only in very specific places. Everywhere else they
should either be null (are not filled out in this context, or are
otherwise valid and can be used by the callee) or are valid (i.e., point
at something meaningful) in some manner.

That is, we do not malloc stuff a willy-nilly, freeing things whenever.
There are routines that allocate a chunk of memory to store a number
of structs and lists of structs (handling any allocation errors there),
and there are routines that these things up when we are done. There are
a few places where we allocate space for something, but it is generally
allocated and freed within the same function. None of our debug lines
would use such a pointer after it had been freed.

Violating this in the routines that have debug statements, when
debugging is enabled, will cause some sort of undefined behaviour. If
we catch it (whether or not the debug raises the problem) we would fix it.
Jan 26 '07 #38
Ok, so maybe i'm way off base here, but

a) why is a variable not initialized to say, NULL when it is declared
but the programmer forgot to assign some useful value to it? This also
would implicate to me that when free() frees a ptr, it assigns it null.
What other value could it possible have ? At least for pointers, it's
bad for them to point at nothingness, so why not always set them to
NULL ? I don't think this would impair the language in anyway or does
it?

I understand that it's the responsibility of the programmer et al, but
i'm pretty sure that by setting it to null _alot_ of problems would be
fixed.

Then again, maybe not :-)

On Jan 26, 9:13 pm, Clever Monkey
<clvrmnky.inva...@hotmail.com.invalidwrote:
santosh wrote:
Clever Monkey wrote:
Richard Tobin wrote:
In article <1169768146.763494.270...@a75g2000cwd.googlegroups .com>,
tedu <t...@zeitbombe.orgwrote:
>>>>It is common practice in many shops I've worked at to have a function or
macro used in debugging routines that can take a pointer and return the
pointer or "null", depending on if the pointer is valid to dereference
or not.
Maybe, but that's not possible in standard C.
why not?
You can tell whether it's null (which I suspect is what was meant) but
you can't check that it's "valid to dereference" - it might be a
free()ed pointer for example.
We check it for null, which is a valid enough check for a debug/logging
routine. If it has been freed and causes the debug to crash, then we
can consider this a "free" assert and can fix it, because we are
generally not interested in the pointer once it has been freed.
So what is done with the pointers after they've been free()'ed?Er, nothing? I'm not sure what you mean. Whether something has been
freed are it has not. Generally, during the lifetime of this library,
things are freed only in very specific places. Everywhere else they
should either be null (are not filled out in this context, or are
otherwise valid and can be used by the callee) or are valid (i.e., point
at something meaningful) in some manner.

That is, we do not malloc stuff a willy-nilly, freeing things whenever.
There are routines that allocate a chunk of memory to store a number
of structs and lists of structs (handling any allocation errors there),
and there are routines that these things up when we are done. There are
a few places where we allocate space for something, but it is generally
allocated and freed within the same function. None of our debug lines
would use such a pointer after it had been freed.

Violating this in the routines that have debug statements, when
debugging is enabled, will cause some sort of undefined behaviour. If
we catch it (whether or not the debug raises the problem) we would fix it.
Jan 27 '07 #39
Err sorry i missed this:
>We check it for null, which is a valid enough check for a debug/logging
routine. If it has been freed and causes the debug to crash, then we
can consider this a "free" assert and can fix it, because we are
generally not interested in the pointer once it has been freed
Care to show how you would implement this ?

On Jan 27, 11:07 am, Alef.V...@gmail.com wrote:
Ok, so maybe i'm way off base here, but

a) why is a variable not initialized to say, NULL when it is declared
but the programmer forgot to assign some useful value to it? This also
would implicate to me that when free() frees a ptr, it assigns it null.
What other value could it possible have ? At least for pointers, it's
bad for them to point at nothingness, so why not always set them to
NULL ? I don't think this would impair the language in anyway or does
it?

I understand that it's the responsibility of the programmer et al, but
i'm pretty sure that by setting it to null _alot_ of problems would be
fixed.

Then again, maybe not :-)

On Jan 26, 9:13 pm, Clever Monkey

<clvrmnky.inva...@hotmail.com.invalidwrote:
santosh wrote:
Clever Monkey wrote:
>Richard Tobin wrote:
>>In article <1169768146.763494.270...@a75g2000cwd.googlegroups .com>,
>>tedu <t...@zeitbombe.orgwrote:
>>>>>It is common practice in many shops I've worked at to have a function or
>>>>>macro used in debugging routines that can take a pointer and return the
>>>>>pointer or "null", depending on if the pointer is valid to dereference
>>>>>or not.
>>>>Maybe, but that's not possible in standard C.
>>>why not?
>>You can tell whether it's null (which I suspect is what was meant) but
>>you can't check that it's "valid to dereference" - it might be a
>>free()ed pointer for example.
>We check it for null, which is a valid enough check for a debug/logging
>routine. If it has been freed and causes the debug to crash, then we
>can consider this a "free" assert and can fix it, because we are
>generally not interested in the pointer once it has been freed.
So what is done with the pointers after they've been free()'ed?Er, nothing? I'm not sure what you mean. Whether something has been
freed are it has not. Generally, during the lifetime of this library,
things are freed only in very specific places. Everywhere else they
should either be null (are not filled out in this context, or are
otherwise valid and can be used by the callee) or are valid (i.e., point
at something meaningful) in some manner.
That is, we do not malloc stuff a willy-nilly, freeing things whenever.
There are routines that allocate a chunk of memory to store a number
of structs and lists of structs (handling any allocation errors there),
and there are routines that these things up when we are done. There are
a few places where we allocate space for something, but it is generally
allocated and freed within the same function. None of our debug lines
would use such a pointer after it had been freed.
Violating this in the routines that have debug statements, when
debugging is enabled, will cause some sort of undefined behaviour. If
we catch it (whether or not the debug raises the problem) we would fix it.
Jan 27 '07 #40


On Jan 27, 11:09 am, Alef.V...@gmail.com wrote:
Err sorry i missed this:
We check it for null, which is a valid enough check for a debug/logging
routine. If it has been freed and causes the debug to crash, then we
can consider this a "free" assert and can fix it, because we are
generally not interested in the pointer once it has been freedCare to show how you would implement this ?

On Jan 27, 11:07 am, Alef.V...@gmail.com wrote:
Ok, so maybe i'm way off base here, but
a) why is a variable not initialized to say, NULL when it is declared
but the programmer forgot to assign some useful value to it? This also
would implicate to me that when free() frees a ptr, it assigns it null.
What other value could it possible have ? At least for pointers, it's
bad for them to point at nothingness, so why not always set them to
NULL ? I don't think this would impair the language in anyway or does
it?
I understand that it's the responsibility of the programmer et al, but
i'm pretty sure that by setting it to null _alot_ of problems would be
fixed.
Then again, maybe not :-)
On Jan 26, 9:13 pm, Clever Monkey
<clvrmnky.inva...@hotmail.com.invalidwrote:
santosh wrote:
Clever Monkey wrote:
Richard Tobin wrote:
>In article <1169768146.763494.270...@a75g2000cwd.googlegroups .com>,
>tedu <t...@zeitbombe.orgwrote:
>>>>It is common practice in many shops I've worked at to have a function or
>>>>macro used in debugging routines that can take a pointer and return the
>>>>pointer or "null", depending on if the pointer is valid to dereference
>>>>or not.
>>>Maybe, but that's not possible in standard C.
>>why not?
>You can tell whether it's null (which I suspect is what was meant) but
>you can't check that it's "valid to dereference" - it might be a
>free()ed pointer for example.
We check it for null, which is a valid enough check for a debug/logging
routine. If it has been freed and causes the debug to crash, then we
can consider this a "free" assert and can fix it, because we are
generally not interested in the pointer once it has been freed.
So what is done with the pointers after they've been free()'ed?Er, nothing? I'm not sure what you mean. Whether something has been
freed are it has not. Generally, during the lifetime of this library,
things are freed only in very specific places. Everywhere else they
should either be null (are not filled out in this context, or are
otherwise valid and can be used by the callee) or are valid (i.e., point
at something meaningful) in some manner.
That is, we do not malloc stuff a willy-nilly, freeing things whenever.
There are routines that allocate a chunk of memory to store a number
of structs and lists of structs (handling any allocation errors there),
and there are routines that these things up when we are done. There are
a few places where we allocate space for something, but it is generally
allocated and freed within the same function. None of our debug lines
would use such a pointer after it had been freed.
Violating this in the routines that have debug statements, when
debugging is enabled, will cause some sort of undefined behaviour. If
we catch it (whether or not the debug raises the problem) we would fix it.
Excusez-moi for the top-post. My bad.

Jan 27 '07 #41
Al*******@gmail.com wrote:

Please don't top-post.
On Jan 26, 9:13 pm, Clever Monkey
santosh wrote:
Clever Monkey wrote:
<snip>
>We check it for null, which is a valid enough check for a debug/logging
>routine. If it has been freed and causes the debug to crash, then we
>can consider this a "free" assert and can fix it, because we are
>generally not interested in the pointer once it has been freed.
So what is done with the pointers after they've been free()'ed?Er, nothing?
I'm not sure what you mean. Whether something has been
freed are it has not. Generally, during the lifetime of this library,
things are freed only in very specific places. Everywhere else they
should either be null (are not filled out in this context, or are
otherwise valid and can be used by the callee) or are valid (i.e., point
at something meaningful) in some manner.
<snip>
Ok, so maybe i'm way off base here, but

a) why is a variable not initialized to say, NULL when it is declared
but the programmer forgot to assign some useful value to it? This also
would implicate to me that when free() frees a ptr, it assigns it null.
No it doesn't. The pointer has an indeterminate value after it has been
free()'ed. You'll have to explicitly set it to null if you want to.
What other value could it possible have ? At least for pointers, it's
bad for them to point at nothingness, so why not always set them to
NULL ? I don't think this would impair the language in anyway or does
it?
Yes, this is a good practise, but as in many other things, C doesn't
force you to do it, or do it behind your back.
I understand that it's the responsibility of the programmer et al, but
i'm pretty sure that by setting it to null _alot_ of problems would be
fixed.
As the "variable initialisation" thread is discussing, pointers which
hold valid, deferencible values or are null would behave more
predictably than uninitialised pointers. Again C doesn't do this
automatically.

Jan 27 '07 #42
Al*******@gmail.com wrote:
>
Ok, so maybe i'm way off base here, but

a) why is a variable not initialized to say, NULL when it is
declared but the programmer forgot to assign some useful value to
it? This also would implicate to me that when free() frees a ptr,
it assigns it null. What other value could it possible have ? At
least for pointers, it's bad for them to point at nothingness, so
why not always set them to NULL ? I don't think this would impair
the language in anyway or does it?

I understand that it's the responsibility of the programmer et al,
but i'm pretty sure that by setting it to null _alot_ of problems
would be fixed.
In part, because such initialization of local storage involves
extra code. In the typical implementation automatic storage is
stack based, and that memory contains whatever was left in it by
previous use. The fact that the extra code is hidden from the
programmer in initialization statements does not affect it. When
you are shoehorning things into a miniscule embedded system it can
make a major difference.

As far as setting pointer to NULL (not null) after free, it can't
be done by the free routine, because parameters are passed by value
in C. free doesn't have access to the pointer.

Please don't top-post. Your answer belongs after, or intermixed
with, the material to which you reply, after snipping irrelevant
material. See the following links:

--
Some informative links:
<http://www.catb.org/~esr/faqs/smart-questions.html>
<http://www.caliburn.nl/topposting.html>
<http://www.netmeister.org/news/learn2quote.html>
<http://cfaj.freeshell.org/google/ (taming google)
<http://members.fortunecity.com/nnqweb/ (newusers)
Jan 27 '07 #43
In article <51*************@mid.individual.net>,
Default User <de***********@yahoo.comwrote:
>Al*******@gmail.com wrote:
>that's what i suspected and wanted to hear, thanks :-)

Please don't top-post. Your replies belong following or interspersed
with properly trimmed quotes. See the majority of other posts in the
newsgroup, or:
<http://www.caliburn.nl/topposting.html>
Get a life!

Jan 27 '07 #44
In article <11**********************@s48g2000cws.googlegroups .com>,
<Al*******@gmail.comwrote:
>a) why is a variable not initialized to say, NULL when it is declared
but the programmer forgot to assign some useful value to it?
In fact, this would be quite reasonable if we were designing C now.
The same analysis that allows most optimising compilers to report
uninitialised variables would allow them to omit the the default
initialisation in almost all cases where it was unnecessary.
>This also
would implicate to me that when free() frees a ptr, it assigns it null.
That's not practical in a language like C. free() does not have
access to the variable whose value is passed to it, even assuming that
it *is* a variable rather than an expression. And of course there may
be many other variables pointing to the same free()ed memory.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Jan 27 '07 #45
Al*******@gmail.com writes:
[69 lines deleted]
Excusez-moi for the top-post. My bad.
Ok, but you should also remember to trim anything that's not relevant
to your followup. The point is for each article to be make sense on
its own.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 27 '07 #46
Flash Gordon wrote:
Harald van Dijk wrote, On 26/01/07 08:35:
Keith Thompson wrote:

<snip>
The correct way to print the value of a null pointer is:

printf("%p\n", (void*)NULL);

The output is implementation-defined.
I would (and did) use (void *) 0. (void *) NULL is valid in this
context, but not in some others where (void *) 0 is, because it is not
necessarily a null pointer constant. All it is sure to be is a constant
null pointer.

In what context would "(void *)NULL" be invalid but "(void *)0" valid?
Initialisation of (or assignment to) function pointers.

Jan 28 '07 #47
On Jan 25, 4:03 pm, rich...@cogsci.ed.ac.uk (Richard Tobin) wrote:
In article <1169768146.763494.270...@a75g2000cwd.googlegroups .com>,

tedu <t...@zeitbombe.orgwrote:
It is common practice in many shops I've worked at to have a function or
macro used in debugging routines that can take a pointer and return the
pointer or "null", depending on if the pointer is valid to dereference
or not.
Maybe, but that's not possible in standard C.
why not?

You can tell whether it's null (which I suspect is what was meant) but
you can't check that it's "valid to dereference" - it might be a
free()ed pointer for example.
[little slow noticing the followup.] but one can keep a list of freed
pointers (or conversely, a list of all allocated pointers).

assuming a basic list/hash/container library:

void *mymalloc(size_t s) { void *p = malloc(s); if (p)
add(goodpointers, p); return p; }
void myfree(void *p) { if (p && !contains(goodpointers, p)) abort();
free(p); }
int isgood(void *p) { return contains(goodpointers, p); }
Feb 2 '07 #48
tedu wrote:
On Jan 25, 4:03 pm, rich...@cogsci.ed.ac.uk (Richard Tobin) wrote:
In article <1169768146.763494.270...@a75g2000cwd.googlegroups .com>,

tedu <t...@zeitbombe.orgwrote:
It is common practice in many shops I've worked at to have a function or
macro used in debugging routines that can take a pointer and return the
pointer or "null", depending on if the pointer is valid to dereference
or not.
>Maybe, but that's not possible in standard C.
>why not?
You can tell whether it's null (which I suspect is what was meant) but
you can't check that it's "valid to dereference" - it might be a
free()ed pointer for example.

[little slow noticing the followup.] but one can keep a list of freed
pointers (or conversely, a list of all allocated pointers).

assuming a basic list/hash/container library:

void *mymalloc(size_t s) { void *p = malloc(s); if (p)
add(goodpointers, p); return p; }
void myfree(void *p) { if (p && !contains(goodpointers, p)) abort();
free(p); }
int isgood(void *p) { return contains(goodpointers, p); }
In standard C, you're not even allowed to compare a freed pointer for
equality to another pointer.

Feb 2 '07 #49
tedu wrote On 02/02/07 13:28,:
On Jan 25, 4:03 pm, rich...@cogsci.ed.ac.uk (Richard Tobin) wrote:
>>In article <1169768146.763494.270...@a75g2000cwd.googlegroups .com>,

tedu <t...@zeitbombe.orgwrote:
>>>>>It is common practice in many shops I've worked at to have a function or
>macro used in debugging routines that can take a pointer and return the
>pointer or "null", depending on if the pointer is valid to dereference
>or not.

Maybe, but that's not possible in standard C.

why not?

You can tell whether it's null (which I suspect is what was meant) but
you can't check that it's "valid to dereference" - it might be a
free()ed pointer for example.


[little slow noticing the followup.] but one can keep a list of freed
pointers (or conversely, a list of all allocated pointers).

assuming a basic list/hash/container library:

void *mymalloc(size_t s) { void *p = malloc(s); if (p)
add(goodpointers, p); return p; }
void myfree(void *p) { if (p && !contains(goodpointers, p)) abort();
free(p); }
int isgood(void *p) { return contains(goodpointers, p); }
In isgood(p), what if p points to a perfectly valid
object that wasn't obtained from malloc()?

if (isgood(argv)) ...
if (isgood("Hello, world!")) ...
if (isgood(stdout)) ...
if (isgood(&myStruct)) ...

Or, what if p points "into" rather than "at" a block
of allocated memory?

struct s { int i; int j; } *p;
p = mymalloc(sizeof *p); /* assume success */
if (isgood(&p->j)) ...

char *p = mymalloc(100); /* assume success */
strcpy (p, "Hello, world!");
if (isgood(strchr(p, 'o')) ...

Or, what if p points to a block of memory that has
been freed and then reallocated?

double *dp;
char *p = mymalloc(100); /* assume success */
strcpy (p, "Hello");
...
free (p);
dp = mymalloc(sizeof *dp); /* gets same block, by luck */
*dp = 42.0;
if (isgood(p))
strcat (p, ", world!"); /* oops! */

--
Er*********@sun.com
Feb 2 '07 #50

This discussion thread is closed

Replies have been disabled for this discussion.

By using this site, you agree to our Privacy Policy and Terms of Use.