Search code examples
c++new-operatorshared-ptrdelete-operator

Crash in creating an array in the heap and delete it with/without shared_ptr


I am fully aware that if I want to create a smart pointer to an array the best way is to use

     boost::shared_array<T>( new T[20] );

What I don't understand is the crash I have when a shared pointer of this type gets out of scope.

     boost::shared_ptr<T>( new T[20] );

I always thought that the code above would create a leak since it calls delete on the first element of the array by leaving untouched the others but this is not the case and I have a segmentation fault.

Can you help me understanding why? I have worst behavior if I don't use the shared pointer but a plain vanilla pointer

       CMyClass *p = new CMyCLass[10];
       ///....do stuff
       delete p;

       *** glibc detected *** ./test: munmap_chunk(): invalid pointer: 0x088eb00c ***

Solution

  • Can you help me understanding why? I have worst behavior if I don't use the shared pointer but a plain vanilla pointer

    Because your code has an Undefined Behavior.

    CMyClass *p = new CMyCLass[10];
    ///....do stuff
    delete []p;
          ^^^^ <-------------that is Missing!
    

    You need to use delete [].

    1. If you allocated using new you must use delete.
    2. If you allocated using new [] you must use delete []

    Doing otherwise leads to Undefined Behavior. And one its Undefined Behavior then your program might show any behavior.It might crash or work or whatever(literally) so all safe bets are off.

    How to use custom deallocation with shared_ptr?

    For shared_ptr you should use your own custom deletor function to deallocate appropriately. In case of array allocation using new [], you need to use delete []. Something like:

    template
    class CustomDeleter
    {
    public:
        void operator () (T* d) const
        {
            delete [] d;
        }
    };
    
    int main ()
    {
        std::shared_ptr array(new Myclass[256], CustomDeleter());
        return 0;
    }