cs162sbj@uape_5.ucsd.edu (....What Is?....) (05/31/91)
I've become a pretty good beginner at C++ & am ready to move on to intermediate. Before I do, I need some clarifications on C++ that I haven't been able to find in the books I've read. They might be dumb questions, or may have been thoroughly discussed, but here goes anyways. [1] Why aren't pointers hidden/protected/controlled/etc. the way class objects are? I was doing a symbol table for a class project which kept reference counts on all the objects & the objects that they pointed to, and a single pointer assignment in the "main program" from a pointer returned by a member function to a new pointer is enough to throw the reference count off. I want to be able to control pointer assignments the way I can control object assignments, but I haven't been able to overload operators using pointers to objects, just objects. How is what I want to do accomplished cleanly? [2] Why doesn't delete() automatically set the original pointer to NULL? I can't do it from within my destructor, and I can find no reason to leave it pointing to freed memory. Steven Boswell whatis@ucsd.edu
robert@kohlrabi.tcs.com (Robert Blumen) (06/01/91)
In article <19944@sdcc6.ucsd.edu>, cs162sbj@uape_5.ucsd.edu (....What Is?....) writes: |> [1] |> I want to be |> able to control pointer assignments the way I can control object |> assignments, but I haven't been able to overload operators using |> pointers to objects, just objects. How is what I want to do |> accomplished cleanly? Perhaps you can do what you want by overload the per-class operator new, operator delete, and operator &. You can also define pointer objects that have the desired semantics (most generically done using templates) and use the pointer objects rather than regular pointers for the classes that need ref counts. |> [2] Why doesn't delete() automatically set the original pointer to |> NULL? I can't do it from within my destructor, and I can find no |> reason to leave it pointing to freed memory. |> You could do this yourself by writing your own ::operator delete and linking it into your code. I can't say just why it doesn't do this, since not doing so means that the post-delete pointer value is certainly invalid. It is consistent with the C++ philosophy "it doesn't work this way by default but you can do it yourself" ----------------------------------------------------------------------------- Robert Blumen | rblumen@tcs.com Senior Software Engineer | 2121 Allston Way, Berkeley, CA 94704 Teknekron Communications Systems, Inc. | (415) 649-3759
warsaw@nlm.nih.gov (Barry A. Warsaw) (06/05/91)
>>>>> "Robert" == Robert Blumen <robert@kohlrabi.tcs.com> writes:
Robert> You could do this yourself by writing your own ::operator
Robert> delete and linking it into your code.
Are you sure? Doesn't ::operator delete *require* an argument type of
void* and forbid void*&, which would be necessary if setting the
pointer to zero after deleting would have any effect outside of the
operator? I don't have the ARM around, but I know my 2.0 cfront barfs
on:
void ::operator delete( void*& ptr ) { ... };
CC foo.cc:
"foo.cc", line 7: error: operator delete()'s 1st argument must be a void*
But perhaps I'm missing something?
Robert> I can't say just why it doesn't do this, since not doing
Robert> so means that the post-delete pointer value is certainly
Robert> invalid.
When I asked this question 6-8 months ago, people correctly pointed
out that just setting the pointer to zero won't solve all your
problems, for example in cases where two pointers are referencing the
same object, you delete the first pointer, it gets set to zero, but
then you accidently dereference the second pointer. How are you going
to set all pointers referencing some chunk of memory to zero? Not in
any built-in way, that for sure. And it *does* cost enough
performance-wise to warrant not being built into the language.
Robert> It is consistent with the C++ philosophy "it doesn't work
Robert> this way by default but you can do it yourself"
Hmm. I for one would've liked to see ::operator delete take a void*&
so you *could* do this if you wanted (which, right now, you can't).
Still after listening to what more experienced programmers were
saying, and getting some C++ time under my belt, I think you really
need to take a much more careful approach when throwing pointers to
objects around. Using ::operator delete could lull one into a false
sense of security :-).
-Barry
"When in doubt, cout."
jamshid@ut-emx.uucp (Jamshid Afshar) (06/10/91)
In article <WARSAW.91Jun5120801@warsaw.nlm.nih.gov> warsaw@nlm.nih.gov writes: <<I removed an attempt at creating an operator delete() which sets pointer to 0.>> <<I also removed an example of how aliasing can still cause a reference to freed memory even if delete sets the pointer to 0 .>> > Robert> It is consistent with the C++ philosophy "it doesn't work > Robert> this way by default but you can do it yourself" > >Hmm. I for one would've liked to see ::operator delete take a void*& >so you *could* do this if you wanted (which, right now, you can't). >Still after listening to what more experienced programmers were >saying, and getting some C++ time under my belt, I think you really >need to take a much more careful approach when throwing pointers to >objects around. Using ::operator delete could lull one into a false >sense of security :-). > >-Barry > >"When in doubt, cout." Page 63 of the ARM mentions that modifying the pointer after a delete would be useful for debugging. It would have to be something the compiler does, as there is no way for the programmer to do it by overloading operator delete. operator delete cannot take a reference to a void* because while the _value_ of any object pointer can always be converted to the _value_ of a void*, the actualy object pointer is not a void* (e.g. you can't pass an int** to a void**). This is an important fact that helps in understanding why you can't pass the 'address of a pointer to a Derived' to a function expecting the 'address of a pointer to a Base' (a c.l.c++ faq-- has anyone taken up the challenge of maintaining a FAQ list?). I do believe that setting the pointer to 0 (or some "bad" address) after a delete is well worth the effort as a significant number of bugs are caused by referencing objects after they are deleted. This is a very nasty bug because in alot of C++ implementations, using freed memory will _not_ cause your program to crash (especially during testing :-). I always set the pointer to 0 after a delete in my code and it has caught alot of bugs (one particularly bad one was a compiler bug causing the destructor to be called twice). Of course there is no way to keep another pointer from referencing the freed memory, but the simple case is common enough and easy enough to prevent without a significant performance penalty (I was relieved to see a poster unanimously flamed in comp.lang.c for asserting that testing p!=0 in free(p) is a significant performance penalty "when you have 1000 free's"). I definitely agree that you have to be very careful with pointers in C/C++. Since I've been using C++ I have tried to restrict my use of pointers to private class member variables and rarely even use them there because of references or my complete disregard for efficiency :). "Smart" pointers, objects that behave like pointers but keep a reference count and can do other checking, seem like they would be helpful, but I've never actually created a smart pointer class for any of my classes. Does anyone have a simple example they can post? It seems like templates would help in creating smart pointers. As a matter of fact, it seems like templates would help in alot of non-obvious (at least to me) ways. For example, someone posted a while back a simple template which would "automaticly" create operator!=() if your class defined a operator==()). Jamshid Afshar jamshid@emx.utexas.edu "Keep sigs short."
2195bm@gmuvax.gmu.edu (06/10/91)
In article <50253@ut-emx.uucp>, jamshid@ut-emx.uucp (Jamshid Afshar) writes: > 'address of a pointer to a Base' (a c.l.c++ faq-- has anyone taken up Hmmm: faq-- Does this mean Read the whole FAQ list, then delete the least- frequently asked question? // john porter