1

So I'm building a a linked list class, with stack-like functionality (LIFO), to hold instances of a Node class:

enum Sides{NorthWest=0, North=1, NorthEast=2, West=3, East=4, SouthWest=5, South=6, SouthEast=7};

class Node
{
    public:
    Node(position2df pos, int id):nextNode(NULL)
    {
        position=pos;
        ID=id;
    }
    ~Node(){}

    position2df getPosition(){return position;}
    int getID(){return ID;}

    void setPeripheralID(Sides side, int id){peripheralID[side]=id;}
    int getPeripheralID(Sides side){return peripheralID[side];}

    Node *nextNode;

    private:
    position2df position;
    int ID;
    int peripheralID[8];
};

class NodeList
{
    public:
    NodeList()
    {
        root=NULL;
        end=NULL;
    }
    ~NodeList(){}

    /// Function for adding elements to the list.
    void push(position2df pos, int id)
    {
        if(root==NULL)
        {
            root=new Node(pos, id);
            end=root;
        }
        else
        {
            Node *newend=new Node(pos, id);
            end->nextNode=newend;
            end=end->nextNode;
        }
    }

    /// Function for removing objects from the list.
    Node *pop()
    {
        slider=root;
        Node *previous;
        Node *next=slider;

        for(previous=NULL; next!=NULL; next=slider->nextNode)
        {
            previous=slider;
            slider=next;
        }

        delete slider;
        end=previous;
        cout << "Can still access deleted object: " << (*slider).getID() << endl;

        return end;
    }

    private:
    Node *root;
    Node *end;
    Node *slider;
};

In the NodeList::Node *pop() function (whose purpose is to delete the last element and reset the previous one as the end of the list), I call delete on the Node class instance pointed by (pointer name) slider. However, even after deleting it I can still access the instance and output its members. I don't know if it matters, but the instance has three different pointers pointing to it at the time of its deletion. They are:

  • Node *slider;
  • Node *end;
  • the previous class instance's Node::Node *nextNode;

I suppose at this point a question is in order :D

If I can still access the instance members after I deleted it how do I know if it was properly deleted?

Is my code going to cause a memory leak?

I guess the ultimate question is: am I doing something wrong?

P.S. There are a couple of variables here (position2df; vector2df;) that come from the Irrlicht Game Engine. Just wanted to point that out to avoid any confusion.

Forgive me if I was vague or otherwise unclear with this post, but I'm not very skilled when it comes to asking questions online.

Chowlett
  • 45,935
  • 20
  • 116
  • 150
Aluthren
  • 416
  • 6
  • 18
  • Check [this](http://stackoverflow.com/questions/11603005/what-does-delete-command-really-do-for-memory-for-pointers-in-c) – Suvarna Pattayil Apr 19 '13 at 10:46
  • @SuvP this is what should be checked: http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope – unkulunkulu Apr 19 '13 at 10:50

6 Answers6

3

If I can still access the instance members after I deleted it how do I know if it was properly deleted?

Just trust the runtime library: if you call delete, the thing is deleted, period. Once you tell the system that you no longer need the memory, you gave it up - it is no longer yours. The system counts it with its available memory to redistribute, so it can give it to other parts of your program upon request. You can still access that memory, and may even find what was there before you gave it up, but that's undefined behavior.

Is my code going to cause a memory leak?

No, because you release the memory that you allocated.

I guess the ultimate question is: am I doing something wrong?

Yes - accessing the memory of deallocated object is wrong (undefined behavior). Other than that, it looks fine.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
1

If things are accessed after being deleted it's not a leak, but it is undefined behavior: aka A crash waiting to happen.

John3136
  • 28,809
  • 4
  • 51
  • 69
0

Deleted objects aren't overwritten immediately. The memory area where they resided is merely marked as "free to use". It won't be overwritten before the memory is reallocated and initialized for some other purpose.

You have no control over when and why this happens, so you should never access memory after deleting it. To ensure this, all pointers which point to a deleted object should be set to null before it is deleted.

Philipp
  • 67,764
  • 9
  • 118
  • 153
  • But typically setting all pointers to NULL after deletion is impossible because that pointer could have been copied many times and you do not know where those pointers are. IMO this is misleading advice, it's not helpful for the typical case, and it's likely to suggest that pointer use can be made safer that it really is. – john Apr 19 '13 at 10:52
0

When using new and delete, you are working with dynamic memory: you either reserve a memory block or free it. When freeing, the it is just annotated as free-to-use, so it can be reused when needed. The program, though, does not dedicate any effort clearing that memory area.

Having a pointer to a freed memory area is possible, and you may be able to read data from there, but be careful, as the data found there may be replaced at any time when the program needs to reserve more memory.

Accessing to a memory area which has been freed is at all times dangerous and may cause program crashes or, even worse, malfunctions.

0

If I can still access the instance members after I deleted it how do I know if it was properly deleted?

after calling delete the memory is not yours any longer and object is considered as deleted

Is my code going to cause a memory leak?

No, if you haven't called delete then it would be a leak, but here you released the memory that you allocated previously, so it is OK.

I guess the ultimate question is: am I doing something wrong?

yes, after calling delete you shouldn't assume that there is still your object, it is undefined behaviour

4pie0
  • 29,204
  • 9
  • 82
  • 118
0

Why can still access class instances after deleting them?

You can't.

If you still have a pointer to the memory that contained the object, you might or might not be able to access its remnants; or perhaps another, unrelated object that has been created since the object was deleted. If you're very lucky, the memory might have been unmapped, and you'll get a friendly segmentation fault to point out the error, but that typically only happens with very large objects.

In short, dereferencing a pointer to a deleted object gives undefined behaviour.

how do I know if it was properly deleted?

By knowing when your program has deleted it, and making sure you don't use any dangling pointers afterwards. This is quite tricky if you're using raw pointers and calling delete directly, which is why you should usually manage dynamic memory with RAII types such as containers and smart pointers.

Is my code going to cause a memory leak?

As far as I can see, there's no leak in the pop function; if you used smart pointers, you could make it more obviously correct.

The destructor doesn't delete anything so, unless you've got something else responsible for deleting the list's contents, you will leak anything left in it when the list is destroyed.

I guess the ultimate question is: am I doing something wrong?

If you did add a destructor to fix the leak, you'd also need to add (or delete) the copy constructor and copy-assignment operator to prevent double deletion if you were to copy the list. This is sometimes known as the Rule of Three and is very important when writing resource-management classes. If you were to use smart pointers, they would take care of all that for you, and you can follow the much simpler "Rule of Zero" (i.e. just let the compiler generate those three things for you).

Community
  • 1
  • 1
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644