What is responsible for deleting my pointer?

I often wondered

I know that I can create a pointer to an object instance at the same time passing the same pointer as the function argument using the new keyword. Like mine below in the Animation::newFrame function shown in the example below.

However, I also know that, as a general rule, I am responsible for calling delete for the things that I create using new .

So, when I call the Frame constructor as follows:

 Frame* myFrame = new Frame(new point(0,0), new point(100,100), new point(50,20)); 

Where is the responsibility for freeing memory for the 3 points that I created with new in the function call above?

After all, the above 3 new points definitely don't have names for calling delete on.

I always thought that they belong to the scope of the function in which they are called, and they just go out of scope with the function. However, lately I thought that this is not so.

I hope I was clear enough here.

Thanks in advance,

Guy

 struct Frame { public: point f_loc; point f_dim; point f_anchor; //the main constructor:: Creates a frame with some specified values Frame(point* loc, point* dim, point* anchor) { f_loc = loc; f_dim = dim; f_anchor = anchor; } }; struct Animation { public: vector<Frame*> frameList; //currFrame will always be >0 so we subtract 1 void Animation::newFrame(int &currFrame) { vector<Frame*>::iterator it;//create a new iterator it = frameList.begin()+((int)currFrame);//that new iterator is //add in a default frame after the current frame frameList.insert( it, new Frame( new point(0,0), new point(100,100), new point(50,20))); currFrame++;//we are now working on the new Frame } //The default constructor for animation. //Will create a new instance with a single empty frame Animation(int &currFrame) { frameList.push_back(new Frame( new point(0,0), new point(0,0), new point(0,0))); currFrame = 1; } }; 

EDIT: I forgot to mention that this question is purely theoretical. I know that there are much better alternatives to source pointers, such as smart pointers. I ask you to simply deepen your understanding of conventional pointers and how to manage them.

Also the above example is taken from my project, which is actually a mixed C ++ / cli and C ++ (managed and unmanaged classes), so the constructor accepts only point* and does not pass by value ( point ). Since point is an unmanaged structure, therefore, when used in managed code, you need to control yourself, the programmer. :)

+6
source share
7 answers

Refining and, often, ensuring the semantics of resource ownership is the responsibility of the programmer. This can be tricky, especially when it comes to raw pointers, like you are here, in an environment where resource ownership is not given any real consideration. The latter is common not only in toy programs written by novice programmers, but also in production systems written by people with many years of experience who should have known better.

In your actual case above, the Frame object itself should be responsible for delete for the 3 transferred elements, and regardless of what Frame itself built, it should be responsible for delete ing.

Since resource ownership is such a minefield, programmers have long devised a number of methods to clarify property semantics and make it much more difficult to introduce errors and leaks by careless programmers. Nowadays, in C ++, it is considered best practice to avoid raw pointers and, in fact, dynamic allocation in general when possible, mainly because resource ownership is such a dangerous minefield.

In C ++, the main idiom used to achieve these goals is RAII, and the main tools used are auto_ptr (C ++ 03), unique_ptr , shared_ptr and their ilk. Boost also provides a number of so-called smart pointers. Many of these parallel ones found in C ++ 11 (in fact, the new smart pointers to C ++ 11 were the initial ones developed by Boost), but there are some that go beyond the scope, for example intrusive_ptr .

+11
source

First, your code must be fixed in order to compile it - you probably cannot assign point* to point for example (depending on the implementation of point ).

Once you have done this, the answer to your question is that Animation will need to free everything in its frameList , and Frame will need to free everything passed to point* s. Raw pointers will not be deleted for you.

The best answer (although not quite what you requested) is that you should use shared_ptr or unique_ptr to manage memory - they will delete the selected object for you. This is definitely what I would do for a frameList - make it std::vector<std::shared_ptr<Frame>> .

In this case, there is probably no good reason to use pointers for point (I assume that they are just coordinates and very cheap to copy). I just passed them by value or constant reference, Thus, heap allocations are not involved, and this is much simpler.

+2
source

Garbage collector, smart pointer, sometimes it is automatic (if you select from the stack). In principle, it is you who are responsible, but you can delegate responsibility elsewhere.

+1
source

If the function you are calling does not explicitly declare that it will own the passed delete pointers after they are completed, it is your responsibility to delete everything that you are new yourself.

+1
source

As I can see from your code snippet, the current memory policy is "transfer of ownership." For instance. you create 3 point instances, and then pass them to the frame constructor - from now on, the Frame instance is responsible for managing this 3-point memory. Thus, this means that you need to provide a destructor for the Frame class, which will be responsible for deleting the memory for each of the three points stored as a member.

All of the above is related to the theme of "raw memory", which is not needed in new days. Use smart pointers instead. For example, std :: auto_ptr is a good candidate here (but remember some traps: if you copy one auto_ptr to another, the source will be cleared to NULL, the destination will have memory). Another common candidate here is boost :: shared_ptr (it is even included in recent C ++ standards as part of the tr1: :) namespace. And don't forget: you must understand the memory policy for the smart pointer you have chosen. Otherwise, you will end the conversation with the ghosts of destroyed specimens, or your specimens will never be freed, like a genie in a bottle.

+1
source

It depends on the agreements. This is similar to part of the graphical user interface and the usual conventions in the graphical interface are that the containing object becomes responsible for delete after the pointer has been passed. Thus, Animation will delete all pointers in the frameList in its destructor and Frame will delete any pointers that it holds in its destructor. (Note that this convention is very specific to the GUI, however, and that in most other contexts other conventions will be used.)

Having said that, it is also very atypical in C ++ for a value like Point for dynamic allocation, and there would be no pointers to them.

+1
source

Sorry, did not read completely. Responsibility for deleting just created objects if you do not have references to points that you must create a destructor inside your frame object. http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Fcplr380.htm

  class X { public: // Constructor for class X X(); // Destructor for class X ~X(); }; 

X :: ~ X () is automatically called when the X object is deleted.

Please correct me if I am wrong.

-1
source

Source: https://habr.com/ru/post/954601/


All Articles