Thread: delete and delete[]

  1. #1
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879

    Question delete and delete[]

    Argh! I thought I knew this but I don't, and my book isn't helping either. Originally, I thought that delete is used to free an object created on the heap, while delete[] is used to free an array of objects created on the heap. But my book says that you use delete without the [] for that, so I'm really confused. What do you use delete[] for??
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  2. #2
    Registered User
    Join Date
    Mar 2002
    Posts
    249
    I'm not a master at this, but I'm pretty certain you use delete[] for arrays. syntax is: delete[] (name of array);

  3. #3
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Oh, nvm. The example in the book was:
    Code:
    char* temp;
    temp = new char[256];
    delete temp;
    Maybe it's because temp was a char array. And we all know that those are special in a lot of ways
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  4. #4
    Registered User
    Join Date
    Jun 2003
    Posts
    5
    I think you are right. The "delete" is used to release any storage that is allocated with "new", that is the object on the heap. The "delete []" is used to delete an arrary of objects on the heap.

  5. #5
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Ok, thanks. It's good to know that I haven't screwed up my past 5 or so programs
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  6. #6
    Registered User foniks munkee's Avatar
    Join Date
    Nov 2001
    Posts
    343
    The rule of thumb is.. if you have used new with [], then you should use delete with [].
    char* temp;
    temp = new char[256];
    delete temp;
    This should be:
    char* temp;
    temp = new char[256];
    delete [] temp;
    I think the first example is flawed, it will only release part of the memory that was allocated.

  7. #7
    Registered User dug's Avatar
    Join Date
    Jun 2003
    Posts
    66
    what if you've got a situation like:

    >> CSessionImage **image_vector;
    >> image_vector = new CSessionImage *[num_ds];

    so, a dynamically sized array of pointers to objects [in this case a CSessionImage object]....

    calling:

    >> delete [] image_vector;

    in the local deconstructor, does not slip into the CSessionImage deconstructor as expected. and so does not free the memory allocated for the CSessionImage.

    any ideas?

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    new [n] -> delete[]
    new -> delete

    If you do
    char * p = new char[256];
    delete p;
    nothing bad will happen. This is because char is a primitive type (would work with int, float, etc.). Still it is bad practice.
    The difference lies in objects. Only delete[] calls the destructors of EVERY object in the array, delete does it only for the first.

    Code:
    class cl {
    public:
      cl() { cout << "Constructor" << endl; }
      ~cl() { cout << "Destructor" << endl; }
    };
    
    int main()
    {
      cout << "1" << endl;
      cl * p = new cl[5];
      delete[] p;
    
      cout << "2" << endl;
      p = new cl[5];
      delete p;
    
      return 0;
    }
    Output:
    Code:
    1
    Constructor
    Constructor
    Constructor
    Constructor
    Constructor
    Destructor
    Destructor
    Destructor
    Destructor
    Destructor
    
    2
    Constructor
    Constructor
    Constructor
    Constructor
    Constructor
    Destructor
    unless your compiler has safeguards against that error.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  9. #9
    Registered User
    Join Date
    May 2003
    Posts
    148
    Originally posted by CornedBee

    If you do
    char * p = new char[256];
    delete p;
    nothing bad will happen. This is because char is a primitive type (would work with int, float, etc.).
    No.[16.12] Can I drop the [] when deleteing array of some built-in type (char, int, etc)?

  10. #10
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Never thought about that.

    Global overloading of new...
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  11. #11
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Hmm, that sucks... I paid 90 bucks for this book too
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  12. #12
    Registered User
    Join Date
    May 2003
    Posts
    1,619
    Originally posted by dug
    what if you've got a situation like:

    >> CSessionImage **image_vector;
    >> image_vector = new CSessionImage *[num_ds];

    so, a dynamically sized array of pointers to objects [in this case a CSessionImage object]....

    calling:

    >> delete [] image_vector;

    in the local deconstructor, does not slip into the CSessionImage deconstructor as expected. and so does not free the memory allocated for the CSessionImage.

    any ideas?
    OK, you have an array of pointers. If you want to have deletion of the array delete the objects themselves, you need to explicitly delete the objects. For example, this line:

    image_vector = new CSessionImage *[num_ds];

    creates ZERO objects. It creates and allocates memory for POINTERS, but the pointers don't point to anything. Thus,

    delete[] image_vector;

    destroys zero objects; it only undoes the effect of the new[], which was to allocate memory for pointers. The pointers are deallocated here; any objects they point to are not. So depending on how you allocate objects to be pointed at, you need to use a corresponding means to deallocate the objects.

    However, remember that the two worst things to use in C++ are dynamic arrays and pointers, so dynamic arrays OF pointers are even worse. The reason they are bad is that it's very easy to leak memory in these cases. And the C++ language provides better alternatives to dynamic arrays, and other libraries provide better alternatives to pointers.

    Prefer STL containers like std::vector to an array. Prefer smart pointers like Boost's boost::shared_ptr, boost::weak_ptr, std::auto_ptr, etc. over normal pointers. Be SURE to use the correct type of pointer, though.

    E.g., bad code:

    Code:
    int num_ds = 10;
    CSessionImage **image_vector;
    image_vector = new CSessionImage *[num_ds];
    image_vector[0] = new CSessionImage(/*...*/);
    
    // Now, we need to delete one object and deallocate the whole array:
    
    delete image_vector[0];
    delete[] image_vector;
    This is bad; we explicitly have to delete the one object we created. A slightly better idea:

    Code:
    int num_ds = 10;
    CSessionImage **image_vector;
    image_vector = new CSessionImage *[num_ds];
    for (int i = 0; i < num_ds; ++i)
      image_vector[i] = NULL;
    image_vector[0] = new CSessionImage(/*...*/);
    
    // Now, we need delete any objects that exist, and the array
    // Deleting a pointer to NULL is a no-op by definition.
    
    for (int i = 0; i < num_ds; ++i) delete image_vector[i];
    delete[] image_vector;
    However, this has problems. Say we did stuff in between:

    Code:
    int num_ds = 10;
    CSessionImage **image_vector;
    image_vector = new CSessionImage *[num_ds];
    for (int i = 0; i < num_ds; ++i)
      image_vector[i] = NULL;
    image_vector[0] = new CSessionImage(/*...*/);
    /*
    Other code here
    */
    CSessionImage * temp = image_vector[0];
    
    for (int i = 0; i < num_ds; ++i) delete image_vector[i];
    delete[] image_vector;
    
    /*
    Other code here
    */
    
    temp->Function(); 
    // Crashes because we dereference a pointer that no longer exists
    The above situation happens much more often than you might think. Especially consider the case where you create an object with a dynamic array of pointers like above, and then you make a method in its public interface that allows people to get or set pointers. In this case, it can be easy to delete a pointer before you're done with it. It is also easy to lose an object; if you assign a new pointer to an array member, you need to delete the old object or it can be lost forever (you will lose the only pointer to that object and thus can never delete it).

    A much, much better idea:

    Code:
    int num_ds = 10;
    typedef boost::shared_ptr<CSessionImage> CSI_ptr;
    std::vector<CSI_ptr> image_vector(num_ds);
    image_vector[0] = CSI_ptr(new CSessionImage(/*...*/));
    As long as you are sure to create all CSessionImage objects like this:

    CSI_ptr newPtr(new CSessionImage(/*...*/));

    newPtr will work (almost) just like a CSessionImage pointer; to call CSessionImage::FunctionA():

    newPtr->FunctionA();

    etc.

    The best part? No deletes, anywhere. The vector will deallocate when it's out of scope, the pointers will destroy the object within once the last shared_ptr to that object is gone. Just a simple wrapper around every call to new guarantees you never need to worry about deletion. As long as you have a shared_ptr that is not NULL, you have a valid object pointer; the object cannot have been deleted. If you assign to the vector, and the only existing shared pointer is gone, then the object is deleted. This method solves (almost all) problems related to not being able to free memory. In fact, as long as there are no cycles of pointers (e.g., say A has a pointer to B which has a pointer to C which has a pointer to A) you cannot leak memory with boost::shared_ptr. If you need cycles, read about boost::weak_ptr.

    In general:

    * Use std::vector instead of dynamic arrays of all non-character objects.
    * Use std::string or std::wstring for all strings.
    * Use smart pointers instead of normal pointers. NEVER use auto_ptr within a container, though.
    Last edited by Cat; 06-23-2003 at 02:17 PM.

  13. #13
    Registered User
    Join Date
    Jun 2003
    Posts
    70
    delete and delete[] both can be used to free up dynamically allocated array.

    The difference is : if the array is an array of object, delete will execute only first element's destructor while delete[] will execute destructor of all the array elements.
    Chintan R Naik

  14. #14
    Registered User
    Join Date
    May 2003
    Posts
    148
    >>delete and delete[] both can be used to free up dynamically allocated array.
    Wrong,read the whole thread,or this
    [16.11] What if I forget the [] when deleteing array allocated via new T[n]?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. delete[] problem with release config...
    By mikahell in forum C++ Programming
    Replies: 8
    Last Post: 08-21-2006, 10:37 AM
  2. why delete[] and delete?
    By dude543 in forum C++ Programming
    Replies: 4
    Last Post: 11-26-2005, 11:55 PM
  3. delete[] or delete?
    By X PaYnE X in forum C++ Programming
    Replies: 7
    Last Post: 03-30-2005, 03:16 PM
  4. Memory issue with new[] and delete[]
    By Zarkhalar in forum C++ Programming
    Replies: 24
    Last Post: 08-07-2004, 07:45 AM
  5. using delete to delete an array
    By iain in forum C++ Programming
    Replies: 2
    Last Post: 03-11-2002, 03:53 PM