deleting pointers?

  • Thread starter Bill Cunningham
  • Start date
B

Barry Schwarz

Ok I decided to test something and here it is:

#include <stdio.h>

int main()
{
int a = 50;
int *pointer = &a;
printf("%i\n", pointer);
pointer = NULL;
printf("%i\n", pointer);

How many times have people told you that to print a pointer value you
need to use %p and cast the pointer to void*?
return 0;
}

And the result was this:
-1073742988
0

So (I am not going to say I guess) pointer must be uninitialized and the

Where do you think you have an uninitialized pointer?
 
B

Barry Schwarz

I've gotten errors with setting anything other than a char* to NULL. I
would have to look up what the value of NULL is or simply as someone who
knows off the top of their head what the standard says. Now I can't remember
what they were so I have this idea that NULL is for char* pointers. Of
course please correct me if I'm wrong.

Sorry Bill but there are only 24 hours in a day and that is
demonstrably insufficient for the rate at which you can generate
errors.
 
B

Bill Cunningham

Barry said:
How many times have people told you that to print a pointer value you
need to use %p and cast the pointer to void*?

Never heard of such a thing. %p prints the address in memory that the
pointer points to not what's stored there. I like the dereference method
better anyway. I just don't always know when I need it.

Bill
 
B

Bill Cunningham

Barry said:
How many times have people told you that to print a pointer value you
need to use %p and cast the pointer to void*?

How many times to I have to say I don't use casts unless absolutely
necessarry? And this isn't that time. What are you doing in poor style to
need a cast? What has the great Richard Heathfield said about casting?

Bill
 
K

Keith Thompson

Bill Cunningham said:
How many times to I have to say I don't use casts unless absolutely
necessarry? And this isn't that time. What are you doing in poor style to
need a cast? What has the great Richard Heathfield said about casting?

Printing a pointer value is one of the few cases where a cast is
appropriate. (You could avoid it by assigning to a void*, but it's more
straightforward just to use the cast.)

Printing a pointer value with "%i" is wrong (though it may give you
meaningful results on some systems).

Here's a correct version of your program:

#include <stdio.h>

int main(void)
{
int a = 50;
int *pointer = &a;
printf("%p\n", (void*)pointer);
pointer = NULL;
printf("%p\n", (void*)pointer);
return 0;
}

And here's another program that prints more useful information:

#include <stdio.h>

int main(void)
{
int a = 50;
int *pointer = &a;
printf("pointer = %p, *pointer = %d\n", (void*)pointer, *pointer);
pointer = NULL;
printf("pointer = %p, *pointer does not exist\n", (void*)pointer);
return 0;
}

On my system, the output is:

pointer = 0xbf95a09c, *pointer = 50
pointer = (nil), *pointer does not exist

(Note that the text printed for "%p" is implementation-defined.)
 
B

Bill Cunningham

pete said:
printf("%i\n", *pointer);

Thanks Pete sometimes I'm not quite sure when I need a dereference or
not. Don't listen to that lame style Scwartz mentioned using casts. They're
not the magical thing some people think they are. I have always been against
casting and he knows it.

Bill
 
B

Bill Cunningham

Shao said:
In your earlier example, were you trying to print the pointer value or
the pointed-to object's value? For the former:

printf("%p\n", pointer);

For the latter:

printf("%d\n", *pointer);

I meant the above but I usally use the less used %i rather than %d. It
just started out that way. Avoid casting as much as possible.

Bill
 
B

Bill Cunningham

Keith Thompson wrote:

[snip]
Here's a correct version of your program:

#include <stdio.h>

int main(void)
{
int a = 50;
int *pointer = &a;
printf("%p\n", (void*)pointer);
pointer = NULL;
printf("%p\n", (void*)pointer);
return 0;
}
[snip]

Are you saying then Keith that you would use the above style rather than

printf("%d\n",*pointer);

Which I would actually prefer. There you are looking at the object being
pointed at right?

Bill
 
B

Bill Cunningham

Shao said:
The pointer value _is_ the "memory address" of the pointed-to object,
if I'm not mistaken.

If it the way I've always thought and Keith Thompson has corrected me on
this. I've always believed that some hex value x0ffcac printed from using

printf("%p\n",pointer); printed to the actual location in the stack or
wherever these memory locations are nowadays that the pointer was pointing
too. Maybe I'm wrong then.

Bill
 
K

Keith Thompson

Bill Cunningham said:
Keith Thompson wrote:

[snip]
Here's a correct version of your program:

#include <stdio.h>

int main(void)
{
int a = 50;
int *pointer = &a;
printf("%p\n", (void*)pointer);
pointer = NULL;
printf("%p\n", (void*)pointer);
return 0;
}
[snip]

Are you saying then Keith that you would use the above style rather than

printf("%d\n",*pointer);

Which I would actually prefer. There you are looking at the object being
pointed at right?

Right.

If you had read the rest of my article, you would have seen a
version of the program which prints both the value of the pointer
and the value of what it points to.

If you want to print the value of a pointer, use %p. If you want
to print the value of the object it points to, dereference it.
It makes no sense to say you "prefer" one or the other. Do whichever
one you need to do for your program to work correctly.
 
B

Bill Cunningham

Shao said:
Since both examples were "above," did you mean the second example; the
value of the pointed-to object?

Right. I don't know what that hex value is then if it's not an address
somewhere in memory. That's what I always thought it was that,

printf("%p\n",pointer);

Bill
 
K

Keith Thompson

Bill Cunningham said:
If it the way I've always thought and Keith Thompson has corrected me on
this. I've always believed that some hex value x0ffcac printed from using

printf("%p\n",pointer); printed to the actual location in the stack or
wherever these memory locations are nowadays that the pointer was pointing
too. Maybe I'm wrong then.

I don't know what correction you're referring to, but it's likely
that you misunderstood.

A pointer value *is* the address of the pointed-to object.

If you print a pointer value using printf with a "%p" format, you'll
get some system-specific human-readable textual representation
of the pointer value. That representation commmonly looks like a
hexadecimal number.
 
A

Angel

Sort of, but thinking of pointers as numbers can lead to some dangerous
misconceptions. A pointer value is a location in memory. On some
systems, such a location is represented by a number, or something that
looks very much like a number, but the C language doesn't assume such a
representation.

You're right, I tend to think in implementation-specic terms instead of
the formal language definition. Bad habit. :) Thanks for clarifying.
Yes, you can perform arithmetic on pointers, but only in limited ways.

If memory serves, the only defined arithmetic operations on pointers are:
- test if a pointer is (not) NULL
- compare two pointers (to see if they point to the same object)
- subtract two pointers (yields an integer result of ptrdiff_t)
- add or subtract an integer value to a pointer (only for non-void*
Think about a street address, like "1600 Pennsylvania Avenue". It
includes a number, 1600, but the address as a whole certainly isn't a
number.

On most implementations I have seen, pointers are represented by
hexadecimal numbers, usually with 8 or 12 digits. But you're right,
the language makes no assumptions about what form pointers
take and it would be bad habit for a programmer to do so.
Right. Most systems will trap in some way on attempts to dereference a
null pointer, but the language doesn't guarantee it; instead, it merely
says the behavior is undefined.

At the very least, it may avoid specific kinds of bug exploits.

I see applications dump core on null pointer dereferences every once
in a while in my job as a sysadmin. Usually memory-hungry applications
that probably don't check the returned result of malloc() properly. :)
On the other hand, setting a pointer to NULL does give it a value that
can safely be examined.

I actually forgot to write down that part, it also helps with debugging
as your debugger can check for null pointers.
 
K

Keith Thompson

Angel said:
On most implementations I have seen, pointers are represented by
hexadecimal numbers, usually with 8 or 12 digits. But you're right,
the language makes no assumptions about what form pointers
take and it would be bad habit for a programmer to do so.
[...]

Even if pointers are represented as, say, 32-bit unsigned integers,
there is nothing hexadecimal about that representation. Hexadecimal
is a human-readable *textual* way of portraying a numeric value.
Whenever you see something in hexadecimal, something had to generate
the hex digits from the bits that make up the actual representation,
and put them together into a character string.
 
J

James Kuyper

On 05/09/2011 09:20 AM, Angel wrote:
....
If memory serves, the only defined arithmetic operations on pointers are: ....
- subtract two pointers (yields an integer result of ptrdiff_t)

That operation is only permitted on pointers that point within or one
element beyond the end of the same array. Under precisely those same
restrictions, you can also compare two pointers for relative order.
 
K

Keith Thompson

James Kuyper said:
On 05/09/2011 09:20 AM, Angel wrote:
...

That operation is only permitted on pointers that point within or one
element beyond the end of the same array. Under precisely those same
restrictions, you can also compare two pointers for relative order.

And that same restriction applies to many other operations on pointers.
Given pointers p, p1, and p2, and an integer i:

p + i, p - i, and i + p are valid only if the result points into, or
just past the end of, the same array object as p.

p1 - p2 is valid only if p1 and p2 both point into, or just past the
end of, the same array object.

p1 < p2, p1 <= p2, p1 > p2, and p1 >= p2 are valid only if [as
above]

But p1 == p2 and p1 != p2 are valid even if p1 and p2 point to distinct
objects, or if one or both are null pointers.

For these purposes, a single object is equivalent to an array with one
element.
 
S

Shao Miller

    I have seen person in another place talking about deleting pointers. I
know in C++ they have new but can that be done in C? All I am aware of is
the NULL pointer. Just thought I'd inquire.

If you want to 'free()' the pointed-to object and "delete" your
pointer by overwriting it with 'NULL' all in one place, I think you
could use:

#define free_with_clear(ptr) (free(ptr), ptr = NULL)

and use 'free_with_clear()', instead, wherever you'd normally use
'free()'. I think that this could help to guard against accidental re-
use, if your implementation simply terminates your program upon a null
pointer dereference.

You could even do:

#if BE_SAFE
# define my_free(ptr) (free(ptr), ptr = NULL)
#else
# define my_free free
#endif

and use 'my_free()', instead, wherever you'd normally use 'free()'.
Then you could switch the guard against accidental re-use on and off
with:

#define BE_SAFE 1

and:

#define BE_SAFE 0

respectively. :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
474,085
Messages
2,570,597
Members
47,220
Latest member
AugustinaJ

Latest Threads

Top