views:

123

answers:

3

Examine the following code:

This works:

T *p = (std::find( this->first(), this->last(), *pPos ));
if( p != last() )
{
    this->push_back(data);

    T *right = (this->last() - 1);
    T *left  = (this->last() - 2);

    while( *pPos != data )
        std::iter_swap( left--, right-- ); 

    return const_cast<T*>(pPos);
}

This does not:

boost::scoped_ptr<T> p(std::find( this->first(), this->last(), *pPos ));
if( p.get() != last() )
{
    this->push_back(data);

    T *right = (this->last() - 1); 
    T *left  = (this->last() - 2); 

    while( *pPos != data ) 
        std::iter_swap( left--, right-- ); 

    return const_cast<T*>(pPos);
}

The second version gives a runtime error of

Expression: _BLOCK_TYPE_IS_VALID_(pHead->nBlockUse)

meaning that my scoped_ptr went out of scope either too soon or is doing some funky things that invalidate it.

What am I doing wrong with the scoped_ptr?

Addendum:

I can't delete any of the pointers. Is this normal? Even if I delete right/left, I get the same error even though they aren't being referenced anymore at the return.

+7  A: 

boost::scoped_ptr will delete the pointer when it (i.e. boost::scoped_ptr instance) goes out of scope. I don't think you want to delete the pointer, which appears to be an iterator in your class.

CashCow
+4  A: 

scoped_ptr is for use with locally heap-allocated memory. It destroys the contained object and deallocates it when you exit the scope.

Attempting to deallocate memory in the middle of a block, such as would be returned by find, is illegal. Destroying an object without owning it will lead to double destruction, which is also illegal.

Simply don't use scoped_ptr here.

Potatoswatter
Explain downvote?
Potatoswatter
The world may never know. (◞‸◟­)
GMan
@Potatoswatter: I'm not using a vector; this is a Field container that is built like a vector. Iterators are coming soon! Thanks for the advice, however. It's solid.
SoulBeaver
+3  A: 

Assuming this->first()\last() returns a regular pointer, the destructor of whatever p points to will get called when the function ends.

if std::find returns this->last(), the destructor of an uninitialzed variable will get called.

Viktor Sehr