|
Objects and Pointers |
Archon
Member #4,195
January 2004
|
I would like to make a distinction between "Objects" and "Pointers" for this thread: My first question is, does anyone ever delete objects via the pointer as opposed to the original reference that the objects have (who actually newed the object) ie: MyClass* myObject = new MyClass(); MyClass* currentObject = myObject; delete currentObject; ^... with the exception of when an object does not get tracked by the class/function that originates it? eg. BITMAP* load_bitmap(...); Secondly, would it ever be logical to make a programming language/platform that distinguishes between (this post's definition of) pointers and objects? By doing this, delete cannot be invoked by a pointer. This could be used as a simple garbage collector: when the original object (variable) is gone, the object in the heap can be de-allocated. [edit] |
count
Member #5,401
January 2005
|
In my understanding of OOP there is no difference between "myObject" and "currentObject". Both are pointers to the same object. Quote: when the original object (variable) is gone, the object in the heap can be de-allocated.
I don't think that this is a good idea at all. An object should only be deleted by the GC when there is NO pointer pointing to this object.
|
Kibiz0r
Member #6,203
September 2005
|
I think you're trying to add complexity where there should be none. The pointers are both pointers, the only object is the one instance of MyClass that they share. If you need to manage who "owns" an object, use boost::shared_ptr, weak_ptr, or intrusive_ptr. --- |
Archon
Member #4,195
January 2004
|
What about the first question? |
Kibiz0r
Member #6,203
September 2005
|
Well, yeah. Why not? It's the same thing. Sometimes you create an object outside of some class that's meant to manage it or any of a thousand other scenarios. --- |
bamccaig
Member #7,536
July 2006
|
There already is a distinction. An object is an instance whereas a pointer stores a memory address that points to that instance. I'm not really an expert... This may or may not clear things up. Sometimes you need to clean it up from an unoriginal pointer because the original pointer is already destroyed, for example.
Out of curiosity, what happens when you do...
** EDIT ** Apparently deleting from the stack memory (objExample) isn't possible with the delete keyword so delete p_objExample seemingly does nothing. -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
anonymous
Member #8025
November 2006
|
Ideally, the question who owns a pointer should have a very clear answer and a simple policy for each object is never to delete pointers that it hasn't allocated itself, + try to restrict allocation and deallocation to constructor and destructor respectively. Ownership can be transferred, though, as is the case with smart pointers and pointer containers. However, once you have new-ed an object and handed the pointer over to a smart-pointer class, you'd stop using the original pointer and access the object through its new owner. As to the OP's question, I wouldn't use two pointers to the same object in the same scope, and normally I wouldn't expect an arbitrary function to deallocate the pointer I pass to it. In the second code snippet, calling delete on a pointer that hasn't been obtained via new is undefined behaviour. In the first snippet you must be aware of the restriction that the EXAMPLE2 constructor expects a pointer allocated with new, and will result in undefined behaviour otherwise. |
bamccaig
Member #7,536
July 2006
|
anonymous said: In the second code snippet, calling delete on a pointer that hasn't been obtained via new is undefined behaviour. Surprisingly it compiled fine, but you're right - delete seemingly had no effect on the stack object. anonymous said: In the first snippet you must be aware of the restriction that the EXAMPLE2 constructor expects a pointer allocated with new, and will result in undefined behaviour otherwise. If you passed it the address of a stack object instead would that stack object be destroyed when dostuff() returned or would it remain until the application ended? // For example... EXAMPLE2 *dostuff(void) { EXAMPLE objExample; EXAMPLE2 *objExample2 = NULL; objExample.UsefulInt = 5; objExample2 = new EXAMPLE2(&objExample); objExample2->UsefulValue(4); return objExample2; } ** EDIT ** I did a test myself and it didn't seem to actually cause any errors, however, the data had changed which leads me to believe that the memory was released when the dostuff() function returned. Notably, however, it didn't cause my program to crash (at least in this instance). ** EDIT ** On second glance, the value I'm getting for objExample2->mobjExample->UsefulInt doesn't seem to be changing when I rerun the program (though it isn't as expected either)... -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
Kibiz0r
Member #6,203
September 2005
|
Good rule of thumb: Don't mix stack and heap objects. --- |
Wetimer
Member #1,622
November 2001
|
I think you are thinking about ownership. It seems to me that an object is either owned or shared. Sometimes an object is tied to an owner. It should be destroyed when its owner is destroyed. In other cases, the object should remain alive until everybody is done with it. Suppose that I have loaded a product from a database. The product itself is held in a Product class. There is another class ProductEditor which handles creating a GUI to actually edit the product. ProductEditor should own the Product. When the window is closed, the Product should be deallocated. In fact, it may be that while the product is open it should be locked to prevent anybody else from opening. Then when deallocated it should release that lock. I actually dealt with a bug recently where a reference counting pointer was held by another object. Because nothing ever indicated that the object should have been destroyed when the widget was closed, it kept a lock on its record in the database. I'm not aware of any language that makes this distinction or explicitly deals with ownership. Some widgets libraries would have a parent thing which works somewhat like that. The question then is how to implement this. 1. When an object is destroyed, you could deallocate all owned objects. But then anybody else who stored a pointer to it for some reason is now dangling. 2. Use a refence counting solution like boost::shared_ptr, so that dangling pointers do not occour. However, here you no long guarantee that the object will be destroyed at the right time. 3. Use a garbage collecting system, but again you have to make sure that no reference are kept or else the garbage will not be collected! 4. Use weak references, such that when the object is destroyed all the weak pointers reset to zero. The thing is in most cases weak references are non-default. So it would be very easy to accidentally have a strong reference defeating the whole thing. 5. If you actually have a notion of a owned object, then when it is destroyed you could assert that the reference count is actually at zero so that you would know that all references have been removed. <code>if(Windows.State = Crash) Computer.halt();</code> |
|