Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Array of structs and new / delete

I have a struct like this:

class Items 
{
private:
    struct item
    {
        unsigned int a, b, c;
    };
    item* items[MAX_ITEMS];
}

Say I wanted to 'delete' an item, like so:

items[5] = NULL;

And I created a new item on that same spot later:

items[5] = new item;

Would I still need to call delete[] to clean this up? Or won't this be needed since bounds of array items[] are known before compiling?

Is setting that pointer to NULL valid or should I be calling delete there?

like image 583
Daniel Sloof Avatar asked Jan 12 '09 00:01

Daniel Sloof


3 Answers

You need to call delete before setting it to NULL. (Setting it to NULL isn't required, it just helps reduce bugs if you accidentally try to dereference the pointer after deleting it.)

Remember that every time you use new, you will need to use delete later on the same pointer. Never use one without the other.

Also, new [] and delete [] go together in the same way, but you should never mix new [] with delete or new with delete []. In your example, since you created the object with new (rather than new [] which would create an array of objects) you must delete the object with delete (rather than delete []).

like image 168
Paige Ruten Avatar answered Nov 08 '22 10:11

Paige Ruten


As Kluge pointed out, you'd leak the object at index 5 like that. But this one really sounds like you shouldn't do this manually but use a container class inside Item. If you don't actually need to store these item objects as pointers, use std::vector<item> instead of that array of MAX_ITEMS pointers. You can always insert or erase vector elements in the middle as well if you need to.

In case you need to store the objects as pointers (usually if struct item is actually polymorphic, unlike in your example), you can use boost::ptr_vector<item> from Boost.PtrContainer instead.

Example:

class Items {
private:
    struct item {
        unsigned int a, b, c;
    };
    std::vector<item> items;
}

if (items.size() > 5) // (just to ensure there is an element at that position)
    items.erase(items.begin() + 5); // no need to use operator delete at all
like image 32
Pyry Jahkola Avatar answered Nov 08 '22 09:11

Pyry Jahkola


To delete an item use:

delete items[5];

after deleting the item it is advisable to set the deleted pointer to NULL, so you won't have an error if you later delete it again by mistake.

items[5] = NULL

like image 44
Joao Vilaca Avatar answered Nov 08 '22 09:11

Joao Vilaca