tags:

views:

109

answers:

4

Rather than assigning a pointer to NULL, is there any way to set the location in memory the pointer is pointing to, to NULL so that any other pointer pointing to that location will be NULL?

+2  A: 

No. Zeroing the memory will have no effect on pointers to that memory. And of course, you can't zero memory after it's freed.

Matthew Flaschen
+2  A: 

a null pointer means that it does not point to any memory location. Therefore as long as it points to a memory location, there is nothing you can put in that memory location that changes the fact that...it points to a memory location.

This goes to the difference between the null set and the empty set. If I empty a jar of cookies, I still have a jar of cookies (empty set). To have null, I must get rid of the jar completely. Nothing I do to the contents of the jar changes the fact that I have a jar.

tl;dr: no

frankc
What does that last paragraph mean?
GregS
@greg tl;dr = too long, didn't read.
frankc
Technically, you wouldn't have a jar of cookies if you'd emptied it, you'd have a cookie jar - my 6yo son and 4yo daughter had a long discussion on this recently and that was the consensus :-) But it's a good analogy.
paxdiablo
Actually, a NULL pointer points to the memory at memory address 0. You can't store anything at that address on most systems because the operating system won't let you. If you look in your system header files, you'll see something like "#define NULL 0".
Daniel Stutzbach
Actually, Daniel, there's no requirement in ISO C that the underlying value of a NULL pointer be 0, just that the source code treat literal 0 as a null pointer. Some systems have an underlying non-zero bit pattern. In addition it's undefined behaviour to dereference a NULL pointer _according to the standard, no matter what_ the OS thinks. In other words, this is not something the environment has a say over, the standard mandates it.
paxdiablo
+1  A: 

A pointer is merely an address. If the address is 0, on most systems, it would be a null pointer. The data stored in the address referenced by the pointer is not accessed in any way when checking to see if the pointer is null. That data is only loaded from memory when the pointer is dereferenced.

Mike Pelley
+6  A: 

Rather than trying to protect yourself from your own mistakes, is there any way you could learn from them so that, in future, you won't make the same mistakes again? :-)

All these sorts of things, such as setting pointers to NULL when the memory behind them is freed, or using "safe" string functions, belie the fact that even the use of so-called unsafe things can be perfectly safe in the hands of people that know what they're doing.

My suggestion is to either learn the gotchas of any language you want to use or move to a language that you feel safer with. What you're talking about is something like reference counting and there are many languages that have this (Objective-C springs to mind for one).

But, if you're going to, or are forced to, code in C, learn the language, including it's dark side - you'll become a much better coder for it.


As an aside, I think what you're asking for is a way to track aliases of a pointer so that, if you free the memory behind one, all aliases are automagically set to NULL:

char *x = malloc(50);
char *y = x;
free (x);
// Both x and y are now magically set to NULL.

You could achieve this this by doing a form of indirection in C. In other words, intercept malloc (manually or using some gcc-like lazy binding trickery) so that, instead of returning a pointer to an allocated block, it returns a pointer to an allocated pointer to an allocated block.

The free calls would also have to be modified so that they freed the block but not the allocated pointer (which would be set to NULL). Indirection operations within your code would then have to be double indirections (**x instead of *x):

char **x = mymalloc(50);
char **y = x;
myfree (x);
// Both *x and *y are now magically set to NULL.

In graphical form:

+---+
| x | -+
+---+  |   +--------+      +------+
       +-> | tmp000 | ---> | data |
+---+  |   +--------+      +------+
| y | -+
+---+

When you called myfree, the data would be freed but not the tmp000 pointer. It would be set to NULL so that, whether you used x or y to try and get to the data, you would get an error.

Of course, this has the problem of leaving pointers lying around and the added problem that the first decent C coder that saw this code would track you down and beat you to a pulp :-)


The "pointers lying around" problem could probably be solved by using a reference count in tmp000 but you'd have to ensure all copies of the pointer were tracked, such as with char **y = mydup(x);.

The "beating you to a pulp" problem is, for all intents and purposes, insoluble.

paxdiablo
_bloody_ pulp, to be precise :) I'm now looking at 'inherited' code full of `my_free((void **)` .. and its my job to get it working on a strict platform. Those who blindly dereference type punned pointers in the name of 'safety' (because they lose track of their pointers) shall be lynched.
Tim Post