Is there anything wrong with the following ?

R

Roubles

Hi All,

Here's my problem, I have a bunch of code that passes an allocated
object (say obj) to a function, and then dereferences that allocated
object when the function returns:

foo(obj);
obj->foobar = TRUE;

The issue is that foo *might* free obj. So the dereference can be
invalid.
I know the orthodox solutions to this problem are -
a) pass obj by reference and let foo set it to NULL.
b) have foo return a bool indicating that obj was free'd

I can't employ any of the orthodox solutions because there is too much
base code (foo comes from a set of a *huge* number of functions).

I am thinking of something like this:

int destroyed;

destroyed = 0;
obj->destroyed = &destroyed;
foo(obj); //obj has its own free routine, in which we can check
//to see if obj->destoyed has an address populated in
//it, and if it does we set its value to 1.
obj->destroyed = NULL;

if (!destroyed) {
obj->foobar = TRUE;
}

Basically, its like passing an int by reference to foo. The only
difference is that the reference is passed within an object. Does
anyone see anything wrong with the above ? I am wondering because I am
never seen this done before.

Or does anyone have any other suggestions ?

Thanks in advance,
roubles
 
A

Alex

Roubles said:
Here's my problem, I have a bunch of code that passes an allocated
object (say obj) to a function, and then dereferences that allocated
object when the function returns:

foo(obj);
obj->foobar = TRUE;

The issue is that foo *might* free obj. So the dereference can be
invalid.
I know the orthodox solutions to this problem are -
a) pass obj by reference and let foo set it to NULL.
b) have foo return a bool indicating that obj was free'd

I can't employ any of the orthodox solutions because there is too much
base code (foo comes from a set of a *huge* number of functions).

I am thinking of something like this:

int destroyed;

destroyed = 0;
obj->destroyed = &destroyed;
foo(obj); //obj has its own free routine, in which we can check
//to see if obj->destoyed has an address populated in
//it, and if it does we set its value to 1.
obj->destroyed = NULL;

if (!destroyed) {

Here, you might want to:

obj->destroyed = 0;

Just in case you forget to set it to somewhere valid and create a
hard-to-spot bug.
obj->foobar = TRUE;
}

Basically, its like passing an int by reference to foo. The only
difference is that the reference is passed within an object. Does
anyone see anything wrong with the above ? I am wondering because I am
never seen this done before.

It'll certainly work.
Or does anyone have any other suggestions ?

You could use wrapper functions, that manage the was-it-destroyed process
and call down to the real function. Tedious if there are a lot of functions,
but would make the calling code clearer IMHO. Perhaps you could generate the
code with a small program.

If the functions all have the same parameter and return types, or there are
a limited number of variants, you could write function(s) taking a function
pointer to get almost the same effect as above with less effort.

A more radical alternative would be to keep track of what objects exist or
have been destroyed yourself, allowing you to validate a pointer.

Alex
 
E

Eric Sosman

Roubles said:
Hi All,

Here's my problem, I have a bunch of code that passes an allocated
object (say obj) to a function, and then dereferences that allocated
object when the function returns:

foo(obj);
obj->foobar = TRUE;

The issue is that foo *might* free obj. So the dereference can be
invalid.

If foo() can free() an object in which the rest of the
program is still interested, there's something fundamentally
wrong with either foo() or the rest of the program.
I know the orthodox solutions to this problem are -
a) pass obj by reference and let foo set it to NULL.
b) have foo return a bool indicating that obj was free'd

I can't employ any of the orthodox solutions because there is too much
base code (foo comes from a set of a *huge* number of functions).

Sounds like a very peculiar program. Are you trying to
imitate a garbage collector, perhaps?
I am thinking of something like this:

int destroyed;

destroyed = 0;
obj->destroyed = &destroyed;
foo(obj); //obj has its own free routine, in which we can check
//to see if obj->destoyed has an address populated in
//it, and if it does we set its value to 1.
obj->destroyed = NULL;

No good: If `obj' has already been free()d, `destroyed'
has the same problem that you're trying to solve for `foobar'.
if (!destroyed) {
obj->foobar = TRUE;
}

Basically, its like passing an int by reference to foo. The only
difference is that the reference is passed within an object. Does
anyone see anything wrong with the above ? I am wondering because I am
never seen this done before.

It looks like it should work (once you move the reference
to `obj->destroyed' inside the `if').

As for why you've never seen it -- well, I've never seen
anything quite like it, either. What's more, I hope never to
see it again! It looks error-prone as all-get-out: Imagine
what would happen if somebody forgets to clear `obj->destroyed'
after just one of the "*huge*" number of foo() calls. It's a
wart on a blemish on a blister, and I say "A pox upon it!"
Or does anyone have any other suggestions ?

The management of dynamic memory requires discipline. One
way to obtain the necessary discipline without too much pain is
to impose some kind of structure on the proceedings. Two common
patterns (which can sometimes be intermingled) are:

- Localize all the allocating and freeing to a few well-
controlled places. Variation: manage the memory for each
object type in a pair of type-specific functions, rather
like constructors and destructors in some other languages.

- Stick a common memory-management header on every object,
and use this header to do whatever magic you require:
reference counting, garbage collection, et cetera. If
you formulate (and obey) simple rules about what does
and doesn't make an object eligible for being freed, you
won't need to ask "Is it still there?" questions.

What you *don't* want to do is just have every function in
the program feeling like it has the privilege to destroy any
object it wants to, any time it wants to. That is not discipline;
that's anarchy.

I'm afraid these comments are too vague to help you toward
an immediate concrete implementation -- but since you haven't
described what's going on with all these uncivilized functions,
I can't be very specific.
 
M

Malcolm

Roubles said:
Here's my problem, I have a bunch of code that passes an
allocated object (say obj) to a function, and then dereferences that
allocated object when the function returns:

foo(obj);
obj->foobar = TRUE;

The issue is that foo *might* free obj.
You've got a problem already. If foo() frees obj it should at least return a
value to say that it has done so. Better still if foo() is rewritten so it
doesn't free anything and obj is freed in a destructor.
If you can't rewrite foo() then there is no good solution.
 

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

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top