3

I have created a pointer of sample class in main. I am passing this pointer to a function function1(). This function has to use pointer as shared pointer and do some operations using this pointer. During exit of function1() destructor of sample in invoked due to shared_ptr. When I pass the same pointer to different function, this pointer is no more valid and program crashes.

1.How do I defer delete operation ( destruction invocation) in function1()?

2.What is the alternative way, so that I can pass pointer to different functions and use it safely, though some of the function are using pointer as shared_ptr?

Here I have sample code and output.

#include <memory>
#include <iostream>
#include <string.h>

using namespace std;

class sample
{
    private:
        char * data;

    public:
        sample( char * data )
        { 
            cout << __FUNCTION__ << endl;
            this->data = new char[strlen( data)];
            strcpy( this->data, data ); 

        }
        ~sample()
        {
            cout << __FUNCTION__ << endl; 
            delete this->data; 
        }
        void print_data()
        { 
            cout << __FUNCTION__ << endl;
            cout << "data = " << this->data << endl;
        }
};

void function1( sample * ptr )
{
    shared_ptr<sample> samp( ptr );
    /* do something with samp */
    ptr->print_data();
}

void function2( sample * ptr )
{
    ptr->print_data();
}

int main()
{
    char data[10] = "123456789";
    data[10] = '\0';
    sample * s = new sample( data );

    function1( s );
    function2( s );

    return 0;
}

output:

sample
print_data
data = 123456789
~sample
print_data
data = 
timrau
  • 22,578
  • 4
  • 51
  • 64
Sandy
  • 159
  • 1
  • 2
  • 15
  • You have an off-by-one error in the `sample` constructor. You forget that C-style strings have an extra terminating character. Use [`std::string`](http://en.cppreference.com/w/cpp/string/basic_string) for strings. – Some programmer dude May 25 '15 at 07:03
  • You *also* have a off-by-one error when you do `data[10] = '\0';`. Since you initialize the array with a string, and the array is big enough, it will already be terminated, no need to add another terminator. Again, use [`std::string`](http://en.cppreference.com/w/cpp/string/basic_string) for strings in C++. – Some programmer dude May 25 '15 at 07:09
  • 3
    Why `function1` need `shared_ptr` ? Does it take ownership of sample ? – Jarod42 May 25 '15 at 07:11
  • 1
    You *should not do this*. The code you have written is using smart pointers in a fundamentally misguided way; you should strive to rewrite the code so that it uses smart pointers in the way they were intended, rather than try to hack things so that it will work as is. –  May 25 '15 at 07:14

2 Answers2

4

Change

sample * s = new sample( data );

into

shared_ptr<sample> s(new sample( data ));

and pass the shared poiter to all functions. It will be deleted when this variable gets out of scope, so late enough for your purposes

marom
  • 5,064
  • 10
  • 14
4

You should not do this. If you want to share ownership of a pointer, then it should be created as a shared_ptr, and passed around as a shared_ptr to functions that also want to share ownership.

That said, just in case you really know what you're doing and you have to hack things to make this work, you can use a custom deleter that does nothing:

struct null_deleter {
    // Generic so it will work with any type!
    template< typename T >
    void operator()(T *p) const {}
};

void function1( sample * ptr )
{
    shared_ptr<sample> samp( ptr, null_deleter() );

    // I really hope this function isn't expecting
    // me to actually share ownership with it....
    something(samp); 

    ptr->print_data();
}