smart array ptr that reliquishes ownership

Discussion in 'C++' started by Nick Keighley, Sep 19, 2011.

  1. Hi!

    I'm looking for something that allows me transfer ownership away from
    a smart array ptr. I basically want the semantics that auto_ptr
    provided.

    auto_ptr<T> myT (new T);
    do_stuff_with_myT;
    anotherT = myT.get();
    myT.release();

    I'd like a smart pointer that did the same but used new[] and delete[]
    internally.

    boost::shared_array doesn't seem to be what I want as it deletes the
    original array when release is called.
     
    Nick Keighley, Sep 19, 2011
    #1
    1. Advertising

  2. On 9/19/2011 10:31 AM, Nick Keighley wrote:
    > Hi!
    >
    > I'm looking for something that allows me transfer ownership away from
    > a smart array ptr. I basically want the semantics that auto_ptr
    > provided.
    >
    > auto_ptr<T> myT (new T);
    > do_stuff_with_myT;
    > anotherT = myT.get();
    > myT.release();
    >
    > I'd like a smart pointer that did the same but used new[] and delete[]
    > internally.
    >
    > boost::shared_array doesn't seem to be what I want as it deletes the
    > original array when release is called.


    I think that smart pointers should transfer the ownership only if you
    assign them instead of doing '.get()' followed by '.release()'...

    Basically something like this:

    auto_ptr<T> myT(new T):
    ...
    anotherT = myT;

    and nothing else.

    V
    --
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Sep 19, 2011
    #2
    1. Advertising

  3. On Sep 19, 3:36 pm, Victor Bazarov <> wrote:
    > On 9/19/2011 10:31 AM, Nick Keighley wrote:
    >
    >
    >
    >
    >
    > > Hi!

    >
    > > I'm looking for something that allows me transfer ownership away from
    > > a smart array ptr. I basically want the semantics that auto_ptr
    > > provided.

    >
    > >     auto_ptr<T>  myT (new T);
    > >     do_stuff_with_myT;
    > >     anotherT = myT.get();
    > >     myT.release();

    >
    > > I'd like a smart pointer that did the same but used new[] and delete[]
    > > internally.

    >
    > > boost::shared_array doesn't seem to be what I want as it deletes the
    > > original array when release is called.

    >
    > I think that smart pointers should transfer the ownership only if you
    > assign them instead of doing '.get()' followed by '.release()'...
    >
    > Basically something like this:
    >
    >      auto_ptr<T> myT(new T):
    >      ...
    >      anotherT = myT;
    >
    > and nothing else.


    I should have been clearer. I want anotherT to be an ordinary dumb
    pointer (I known not a good thing to use, but it's an existign code-
    base and I can't rewrite all at once).

    upDatePtr (T* uP)
    {
    auto_ptr<T> myT(new T):
    some_stuff_that_might_go_wrong;
    uP = myT.get();
    myT.release();
    }
     
    Nick Keighley, Sep 19, 2011
    #3
  4. On 9/19/2011 11:37 AM, Nick Keighley wrote:
    > On Sep 19, 3:36 pm, Victor Bazarov<> wrote:
    >> On 9/19/2011 10:31 AM, Nick Keighley wrote:
    >>
    >>
    >>
    >>
    >>
    >>> Hi!

    >>
    >>> I'm looking for something that allows me transfer ownership away from
    >>> a smart array ptr. I basically want the semantics that auto_ptr
    >>> provided.

    >>
    >>> auto_ptr<T> myT (new T);
    >>> do_stuff_with_myT;
    >>> anotherT = myT.get();
    >>> myT.release();

    >>
    >>> I'd like a smart pointer that did the same but used new[] and delete[]
    >>> internally.

    >>
    >>> boost::shared_array doesn't seem to be what I want as it deletes the
    >>> original array when release is called.

    >>
    >> I think that smart pointers should transfer the ownership only if you
    >> assign them instead of doing '.get()' followed by '.release()'...
    >>
    >> Basically something like this:
    >>
    >> auto_ptr<T> myT(new T):
    >> ...
    >> anotherT = myT;
    >>
    >> and nothing else.

    >
    > I should have been clearer. I want anotherT to be an ordinary dumb
    > pointer (I known not a good thing to use, but it's an existign code-
    > base and I can't rewrite all at once).
    >
    > upDatePtr (T* uP)
    > {
    > auto_ptr<T> myT(new T):
    > some_stuff_that_might_go_wrong;
    > uP = myT.get();
    > myT.release();
    > }


    Let's agree on posting real code. If you meant

    void upDatePtr(T* uP)
    {

    (and then as written), then changing the value of 'uP' seems gratuitous
    because the value is lost (memory leak) when the function returns.

    Perhaps you meant

    void updatePtr(T*& uP)

    which means the value is retained beyond the body of the function.

    In that case you need to make use of 'release's return value:

    void updatePtr(T*& uP)
    {
    auto_ptr<T> myT(new T);
    ..
    uP = myT.release();
    }

    Note that 'std::auto_ptr::release' does *not* delete the pointer.

    V
    --
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Sep 19, 2011
    #4
  5. On Monday, September 19, 2011 5:37:46 PM UTC+2, Nick Keighley wrote:
    > On Sep 19, 3:36 pm, Victor Bazarov <> wrote:
    > > On 9/19/2011 10:31 AM, Nick Keighley wrote:
    > >
    > >
    > >
    > >
    > >
    > > > Hi!

    > >
    > > > I'm looking for something that allows me transfer ownership away from
    > > > a smart array ptr. I basically want the semantics that auto_ptr
    > > > provided.

    > >
    > > >     auto_ptr<T>  myT (new T);
    > > >     do_stuff_with_myT;
    > > >     anotherT = myT.get();
    > > >     myT.release();

    > >
    > > > I'd like a smart pointer that did the same but used new[] and delete[]
    > > > internally.

    > >
    > > > boost::shared_array doesn't seem to be what I want as it deletes the
    > > > original array when release is called.

    > >
    > > I think that smart pointers should transfer the ownership only if you
    > > assign them instead of doing '.get()' followed by '.release()'...
    > >
    > > Basically something like this:
    > >
    > >      auto_ptr<T> myT(new T):
    > >      ...
    > >      anotherT = myT;
    > >
    > > and nothing else.

    >
    > I should have been clearer. I want anotherT to be an ordinary dumb
    > pointer (I known not a good thing to use, but it's an existign code-
    > base and I can't rewrite all at once).
    >
    > upDatePtr (T* uP)
    > {
    > auto_ptr<T> myT(new T):
    > some_stuff_that_might_go_wrong;
    > uP = myT.get();
    > myT.release();
    > }


    Maybe you can use the new C++0x std::unique_ptr< T > in replacement of the deprecated std::auto_ptr< T > that provides a specialization for T[] that calls delete[].

    upDatePtr( T*& uP )
    {
    std::unique_ptr< T[] > myT( new T[ SIZE ] );
    some_stuff_that_might_go_wrong;
    uP = myT.get();
    myT.release();
    }

    Cheers,
    Fulvio Esposito
     
    Fulvio Esposito, Sep 19, 2011
    #5
  6. On Sep 19, 11:37 am, Nick Keighley <>
    wrote:

    > I should have been clearer. I want anotherT to be an ordinary dumb
    > pointer (I known not a good thing to use, but it's an existign code-
    > base and I can't rewrite all at once).
    >
    > upDatePtr (T* uP)
    > {
    >       auto_ptr<T> myT(new T):
    >       some_stuff_that_might_go_wrong;
    >       uP = myT.get();
    >       myT.release();
    > }



    You're looking for std::unique_ptr which is new in C++11 and lives in
    <memory>

    upDatePtr (T*& uP)
    {
          std::unique_ptr<T[]> myT(new T[3]):
          some_stuff_that_might_go_wrong;
          uP = myT.get();
          myT.release();
    }

    If you've got an up-to-date compiler, there's a good chance you have
    unique_ptr.

    Howard
     
    Howard Hinnant, Sep 19, 2011
    #6
  7. Nick Keighley

    Goran Guest

    On Sep 19, 4:31 pm, Nick Keighley <>
    wrote:
    > Hi!
    >
    > I'm looking for something that allows me transfer ownership away from
    > a smart array ptr. I basically want the semantics that auto_ptr
    > provided.
    >
    >    auto_ptr<T> myT (new T);
    >    do_stuff_with_myT;
    >    anotherT = myT.get();
    >    myT.release();
    >
    > I'd like a smart pointer that did the same but used new[] and delete[]
    > internally.


    Erm... Not new[], that's your part of work.

    > boost::shared_array doesn't seem to be what I want as it deletes the
    > original array when release is called.


    Some time ago, I copy-pasted auto_ptr into (what I called)
    auto_ptr_vec, for that exact purpose, and to get that "delete[]".

    Alternatively, +1 for unique_ptr (if available to you).

    Goran.
     
    Goran, Sep 20, 2011
    #7
  8. On Sep 19, 6:23 pm, Victor Bazarov <> wrote:
    > On 9/19/2011 11:37 AM, Nick Keighley wrote:
    > > On Sep 19, 3:36 pm, Victor Bazarov<> wrote:
    > >> On 9/19/2011 10:31 AM, Nick Keighley wrote:



    > >>> I'm looking for something that allows me transfer ownership away from
    > >>> a smart array ptr. I basically want the semantics that auto_ptr
    > >>> provided.

    >
    > >>> auto_ptr<T> myT (new T);
    > >>> do_stuff_with_myT;
    > >>> anotherT = myT.get();
    > >>> myT.release();

    >
    > >>> I'd like a smart pointer that did the same but used new[] and delete[]
    > >>> internally.


    note well. auto_ptr is *not* what I want.


    > >>> boost::shared_array doesn't seem to be what I want as it deletes the
    > >>> original array when release is called.

    >
    > >> I think that smart pointers should transfer the ownership only if you
    > >> assign them instead of doing '.get()' followed by '.release()'...

    >
    > >> Basically something like this:

    >
    > >> auto_ptr<T> myT(new T):
    > >> ...
    > >> anotherT = myT;

    >
    > >> and nothing else.

    >
    > > I should have been clearer. I want anotherT to be an ordinary dumb
    > > pointer (I known not a good thing to use, but it's an existign code-
    > > base and I can't rewrite all at once).

    >
    > > upDatePtr (T* uP)
    > > {
    > > auto_ptr<T> myT(new T):
    > > some_stuff_that_might_go_wrong;
    > > uP = myT.get();
    > > myT.release();
    > > }

    >
    > Let's agree on posting real code.


    fair point...


    > If you meant
    >
    > void upDatePtr(T* uP)
    > {
    >
    > (and then as written), then changing the value of 'uP' seems gratuitous
    > because the value is lost (memory leak) when the function returns.
    >
    > Perhaps you meant
    >
    > void updatePtr(T*& uP)
    >
    > which means the value is retained beyond the body of the function.
    >
    > In that case you need to make use of 'release's return value:
    >
    > void updatePtr(T*& uP)
    > {
    > auto_ptr<T> myT(new T);
    > ..
    > uP = myT.release();
    > }
    >
    > Note that 'std::auto_ptr::release' does *not* delete the pointer.


    but boost::shared_array does...

    Ok. This is nearer the spirit of the real code (and compiles and runs
    to boot)



    struct T
    {
    int data [127];
    };

    struct Params
    {
    T* arrayOfT;
    };

    bool mayGoWrong ()
    {
    return true;
    }

    void allocate (Params* paramsArg)
    {
    T* temp = new T[10];
    if (mayGoWrong ())
    return; // leaks!

    if (paramsArg->arrayOfT != 0)
    delete[] paramsArg->arrayOfT;

    paramsArg->arrayOfT = temp;
    }

    int main ()
    {
    Params params;
    params.arrayOfT = 0;
    allocate (&params);
    return 0;
    }


    Yes there's lots wrong with this but it's not going to get re-written
    right now.

    the simple fix is to bung in a
    delete[] temp;
    but I was hoping there was some well-known smart pointer that could
    handle this.
     
    Nick Keighley, Sep 20, 2011
    #8
  9. On Sep 20, 8:10 am, Goran <> wrote:
    > On Sep 19, 4:31 pm, Nick Keighley <>
    > wrote:
    >
    > > Hi!

    >
    > > I'm looking for something that allows me transfer ownership away from
    > > a smart array ptr. I basically want the semantics that auto_ptr
    > > provided.

    >
    > >    auto_ptr<T> myT (new T);
    > >    do_stuff_with_myT;
    > >    anotherT = myT.get();
    > >    myT.release();

    >
    > > I'd like a smart pointer that did the same but used new[] and delete[]
    > > internally.

    >
    > Erm... Not new[], that's your part of work.
    >
    > > boost::shared_array doesn't seem to be what I want as it deletes the
    > > original array when release is called.

    >
    > Some time ago, I copy-pasted auto_ptr into (what I called)
    > auto_ptr_vec, for that exact purpose, and to get that "delete[]".


    I didn't think what i was tryign to do was that odd...

    > Alternatively, +1 for unique_ptr (if available to you).
     
    Nick Keighley, Sep 20, 2011
    #9
  10. On 9/20/2011 3:52 AM, Nick Keighley wrote:
    > On Sep 20, 8:10 am, Goran<> wrote:
    >> On Sep 19, 4:31 pm, Nick Keighley<>
    >> wrote:
    >>
    >>> Hi!

    >>
    >>> I'm looking for something that allows me transfer ownership away from
    >>> a smart array ptr. I basically want the semantics that auto_ptr
    >>> provided.

    >>
    >>> auto_ptr<T> myT (new T);
    >>> do_stuff_with_myT;
    >>> anotherT = myT.get();
    >>> myT.release();

    >>
    >>> I'd like a smart pointer that did the same but used new[] and delete[]
    >>> internally.

    >>
    >> Erm... Not new[], that's your part of work.
    >>
    >>> boost::shared_array doesn't seem to be what I want as it deletes the
    >>> original array when release is called.

    >>
    >> Some time ago, I copy-pasted auto_ptr into (what I called)
    >> auto_ptr_vec, for that exact purpose, and to get that "delete[]".

    >
    > I didn't think what i was tryign to do was that odd...


    Odd? Yes, I guess it is.

    If you need an array, 'std::vector' is for you. For a single object
    there are 'std::blah_ptr' templates. With 'std::vector' in place and
    now with move semantics, why bother with naked pointers?

    So, why you don't want to use 'std::vector' is unclear so far. Can you
    elaborate on your design decision?

    >> Alternatively, +1 for unique_ptr (if available to you).


    V
    --
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Sep 20, 2011
    #10
  11. On 9/20/2011 3:52 AM, Nick Keighley wrote:
    > On Sep 19, 6:23 pm, Victor Bazarov<> wrote:
    >> On 9/19/2011 11:37 AM, Nick Keighley wrote:
    >>> On Sep 19, 3:36 pm, Victor Bazarov<> wrote:
    >>>> On 9/19/2011 10:31 AM, Nick Keighley wrote:

    >
    >
    >>>>> I'm looking for something that allows me transfer ownership away from
    >>>>> a smart array ptr. I basically want the semantics that auto_ptr
    >>>>> provided.

    >>
    >>>>> auto_ptr<T> myT (new T);
    >>>>> do_stuff_with_myT;
    >>>>> anotherT = myT.get();
    >>>>> myT.release();

    >>
    >>>>> I'd like a smart pointer that did the same but used new[] and delete[]
    >>>>> internally.

    >
    > note well. auto_ptr is *not* what I want.
    >
    >
    >>>>> boost::shared_array doesn't seem to be what I want as it deletes the
    >>>>> original array when release is called.

    >>
    >>>> I think that smart pointers should transfer the ownership only if you
    >>>> assign them instead of doing '.get()' followed by '.release()'...

    >>
    >>>> Basically something like this:

    >>
    >>>> auto_ptr<T> myT(new T):
    >>>> ...
    >>>> anotherT = myT;

    >>
    >>>> and nothing else.

    >>
    >>> I should have been clearer. I want anotherT to be an ordinary dumb
    >>> pointer (I known not a good thing to use, but it's an existign code-
    >>> base and I can't rewrite all at once).

    >>
    >>> upDatePtr (T* uP)
    >>> {
    >>> auto_ptr<T> myT(new T):
    >>> some_stuff_that_might_go_wrong;
    >>> uP = myT.get();
    >>> myT.release();
    >>> }

    >>
    >> Let's agree on posting real code.

    >
    > fair point...
    >
    >
    >> If you meant
    >>
    >> void upDatePtr(T* uP)
    >> {
    >>
    >> (and then as written), then changing the value of 'uP' seems gratuitous
    >> because the value is lost (memory leak) when the function returns.
    >>
    >> Perhaps you meant
    >>
    >> void updatePtr(T*& uP)
    >>
    >> which means the value is retained beyond the body of the function.
    >>
    >> In that case you need to make use of 'release's return value:
    >>
    >> void updatePtr(T*& uP)
    >> {
    >> auto_ptr<T> myT(new T);
    >> ..
    >> uP = myT.release();
    >> }
    >>
    >> Note that 'std::auto_ptr::release' does *not* delete the pointer.

    >
    > but boost::shared_array does...
    >
    > Ok. This is nearer the spirit of the real code (and compiles and runs
    > to boot)
    >
    >
    >
    > struct T
    > {
    > int data [127];
    > };
    >
    > struct Params
    > {
    > T* arrayOfT;
    > };
    >
    > bool mayGoWrong ()
    > {
    > return true;
    > }
    >
    > void allocate (Params* paramsArg)
    > {
    > T* temp = new T[10];
    > if (mayGoWrong ())
    > return; // leaks!
    >
    > if (paramsArg->arrayOfT != 0)
    > delete[] paramsArg->arrayOfT;
    >
    > paramsArg->arrayOfT = temp;
    > }
    >
    > int main ()
    > {
    > Params params;
    > params.arrayOfT = 0;


    This is all _C_. Why don't you switch to C++?

    > allocate (&params);
    > return 0;
    > }
    >
    >
    > Yes there's lots wrong with this but it's not going to get re-written
    > right now.


    Too bad. If it's not now, when?

    >
    > the simple fix is to bung in a
    > delete[] temp;
    > but I was hoping there was some well-known smart pointer that could
    > handle this.


    Yes, it's called std::vector.

    I can almost hear you sighing and mumbling something about the need to
    use some kind of [outdated] third-party library with a C interface.
    Well, there is a clean way - repackage your data *just before calling*
    those functions and *never* maintain naked pointers in your own C++ code.

    You _without a doubt in my mind_ need to rethink your implementation to
    make it closer to what a C++ program ought to be, not keep piling on
    patches of "smart" pointers onto a badly designed one. Bite the bullet,
    do it today, or it's going to be too late.

    V
    --
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Sep 20, 2011
    #11
  12. On Sep 20, 1:20 pm, Victor Bazarov <> wrote:
    > On 9/20/2011 3:52 AM, Nick Keighley wrote:
    > > On Sep 19, 6:23 pm, Victor Bazarov<>  wrote:
    > >> On 9/19/2011 11:37 AM, Nick Keighley wrote:
    > >>> On Sep 19, 3:36 pm, Victor Bazarov<>   wrote:
    > >>>> On 9/19/2011 10:31 AM, Nick Keighley wrote:



    > >>>>> I'm looking for something that allows me transfer ownership away from
    > >>>>> a smart array ptr. I basically want the semantics that auto_ptr
    > >>>>> provided.

    >
    > >>>>>       auto_ptr<T>     myT (new T);
    > >>>>>       do_stuff_with_myT;
    > >>>>>       anotherT = myT.get();
    > >>>>>       myT.release();

    >
    > >>>>> I'd like a smart pointer that did the same but used new[] and delete[]
    > >>>>> internally.

    >
    > > note well. auto_ptr is *not* what I want.

    >
    > >>>>> boost::shared_array doesn't seem to be what I want as it deletes the
    > >>>>> original array when release is called.

    >
    > >>>> I think that smart pointers should transfer the ownership only if you
    > >>>> assign them instead of doing '.get()' followed by '.release()'...

    >
    > >>>> Basically something like this:

    >
    > >>>>        auto_ptr<T>   myT(new T):
    > >>>>        ...
    > >>>>        anotherT = myT;

    >
    > >>>> and nothing else.


    <snip>

    > > Ok. This is nearer the spirit of the real code (and compiles and runs
    > > to boot)

    >
    > > struct T
    > > {
    > >      int data [127];
    > > };

    >
    > > struct Params
    > > {
    > >      T* arrayOfT;
    > > };

    >
    > > bool mayGoWrong ()
    > > {
    > >      return true;
    > > }

    >
    > > void allocate (Params* paramsArg)
    > > {
    > >      T* temp = new T[10];
    > >      if (mayGoWrong ())
    > >          return;    // leaks!

    >
    > >      if (paramsArg->arrayOfT != 0)
    > >         delete[] paramsArg->arrayOfT;

    >
    > >      paramsArg->arrayOfT = temp;
    > > }

    >
    > > int main ()
    > > {
    > >      Params params;
    > >    params.arrayOfT = 0;

    >
    > This is all _C_.  Why don't you switch to C++?


    hey! its got a new in it!

    > >      allocate (&params);
    > >      return 0;
    > > }

    >
    > > Yes there's lots wrong with this but it's not going to get re-written
    > > right now.

    >
    > Too bad.  If it's not now, when?


    incrementally. I was hoping to make things a little better in an
    iterative fashion.

    > > the simple fix is to bung in a
    > >      delete[] temp;
    > > but I was hoping there was some well-known smart pointer that could
    > > handle this.

    >
    > Yes, it's called std::vector.
    >
    > I can almost hear you sighing and mumbling something about the need to
    > use some kind of [outdated] third-party library with a C interface.


    or rather pass the result back to the rest of the application. Yes I'd
    usually replace

    T* temp = new T[10];

    but I want a new[] object that can have ownership transferred

    > Well, there is a clean way - repackage your data *just before calling*
    > those functions and *never* maintain naked pointers in your own C++ code.
    >
    > You _without a doubt in my mind_ need to rethink your implementation to
    > make it closer to what a C++ program ought to be, not keep piling on
    > patches of "smart" pointers onto a badly designed one.  Bite the bullet,
    > do it today, or it's going to be too late.


    I'll give it some serious thought.
     
    Nick Keighley, Sep 20, 2011
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Sid
    Replies:
    5
    Views:
    1,110
  2. Heiko Vogel
    Replies:
    3
    Views:
    598
    Method Man
    Sep 14, 2004
  3. franco ziade

    const ptr to const ptr ?

    franco ziade, Feb 17, 2005, in forum: C Programming
    Replies:
    3
    Views:
    420
    franco ziade
    Feb 17, 2005
  4. G Fernandes
    Replies:
    9
    Views:
    627
    DHOLLINGSWORTH2
    Feb 27, 2005
  5. Jason

    difference between *ptr++ and ++*ptr ?

    Jason, May 15, 2005, in forum: C Programming
    Replies:
    19
    Views:
    6,665
    Chris Torek
    May 19, 2005
Loading...

Share This Page