Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is responsible for deleting my pointer?

I've often wondered,

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

However, I'm also aware that as a general rule I'm responsible for calling delete on things that I create using new.

So when I call Frame's constructor like so:

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

Where does the responsibility to eventually free the memory for the 3 points I have created using new in the above function call lie?

After all, the above 3 new points don't exactly have names for me to call delete on.

I've always sort-of assumed that they belong in the scope of the function they're called in, and they will simply go out of scope with the function. However, lately I've been thinking maybe that is not so.

I hope I've been 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 am aware that there are much better alternatives to raw pointers such as smart pointers. I'm asking simply to deepen my understanding of regular pointers and how to manage them.

Also the example above is taken from a project of mine that is actually C++/cli and c++ mixed (managed and unmanaged classes), so that is why the contructor only accepts point* and not passing by value (point). Because point is an unmanaged structure, and therefore when used within managed code, must be managed by myself, the programmer. :)

like image 949
Guy Joel McLean Avatar asked Sep 25 '13 13:09

Guy Joel McLean


People also ask

What does deleting a pointer mean?

Deleting a pointer (or deleting what it points to, alternatively) means delete p; delete[] p; // for arrays. p was allocated prior to that statement like p = new type; It may also refer to using other ways of dynamic memory management, like free free(p); which was previously allocated using malloc or calloc.

Do smart pointers automatically delete?

To make use of smart pointers in a program, you will need to include the <memory> header file. Smart pointers perform automatic memory management by tracking references to the underlying object and then automatically deleting that object when the last smart pointer that refers to that object goes away.

What happens if a pointer is deleted?

The address of the pointer does not change after you perform delete on it. The space allocated to the pointer variable itself remains in place until your program releases it (which it might never do, e.g. when the pointer is in the static storage area).

Do all pointers need to be deleted?

You don't need to delete it, and, moreover, you shouldn't delete it. If earth is an automatic object, it will be freed automatically. So by manually deleting a pointer to it, you go into undefined behavior. Only delete what you allocate with new .


1 Answers

Clarifying and, often, enforcing the semantics of resource ownership is the responsibility of the programmer. This can be tricky business, especially when dealing with raw pointers as you are here, in an environment where resource ownership hasn't been given any real design consideration. The latter is prevalent not only in toy programs written by rookie programmers, but in production systems written by people with decades of experience who should have known better.

In your actual case above, the Frame object must itself be responsible for deleteing the 3 pointers passed in, and whatever constructed the Frame itself must be responsible for deleteing that.

Because resource ownership is such a minefield, programmers long ago invented a number of techniques to clarify the semantics of ownership, and make it much more difficult to introduce bugs and leaks by careless programmers. These days, in C++ it is considered a best-practice to avoid raw pointers and, in fact, dynamic allocation altogether whenever possible -- in major part because resource ownership is such a dangerous minefield.

In C++, the primary idiom used to accomplish 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 those found in C++11 (in fact, the new smart pointers in C++11 were initialliy developed by Boost), but there are also some that go beyond, such as intrusive_ptr.

like image 87
John Dibling Avatar answered Oct 21 '22 03:10

John Dibling