Search code examples
shared-ptrsmart-pointersallocation

Does shared_ptr free memory allocated on the heap?


So in my job I don't have access to the full std library because....just because (corporate nonsense reasons). I can't use unique_ptr but I have access to shared_ptr and I'm working with c++11. So...

I am using a pre-existing (internal) library function that gets data for me and returns it via a raw point (lets say uint8_t*). And I am want to store this data in my class as a shared_ptr.

According to Will a shared_ptr automatically free up memory?

and http://herbsutter.com/2013/05/29/gotw-89-solution-smart-pointers/

it appears that if I allocate memory on the heap and store this in a shared_ptr, the smart pointer should deallocate the memory (of uint8_t* data) for me. Is this true? Any links to literature would help. Also, from these links it seems that I can't use make_shared because I am "adopting a raw pointer from somewhere else."

class myClass
{
public:
    shared_ptr<uint8_t> iv_data;
    // rest of class
};

other function scope

data_size = getDataSize(...);  // legacy internal function
uint8_t* data = new uint8_t[data_size];
getData(data, data_size); // legacy internal function

myClass object;
object.iv_spd_data = std::shared_ptr<uint8_t>(l_spd_data);

// if scope ends here will I get a memory leak for not freeing data

Solution

  • Here is an example of using shared_ptr<> with an array type and custom deleter. I've added some print statements to show the flow through the program. Note you don't need to know the size allocated when deleting, just that the type is an array. Not deleting with delete[] for an allocated array is undefined behavior; that is why the custom deleter is required.

    See it in action on ideone

    #include <iostream>
    #include <memory>
    #include <cstdint>
    
    using namespace std;
    
    template< typename T >
    struct array_deleter
    {
      void operator ()( T const * p)
      { 
        cout << "using delete[]" << endl;
        delete[] p; 
      }
    };
    
    int8_t* allocate_func()
    {
      cout << "allocating array" << endl;
      return new int8_t[10];
    }
    
    int main() {
        int8_t *ptr = allocate_func();
        cout << "creating smart pointer" << endl;
        shared_ptr<int8_t> sptr(ptr, array_deleter<int8_t>());
        cout << "exiting main" << endl;
        return 0;
    }