1

I have user-defined class like this:

class Test {
public:
    bool opeatator== (const Test& rhs) const {
        return this->value_ == rhs.value_;
    }
    int value_;
};

I saved this pointer with std::list like this:

std::list<Test*> tests_;
tests_.push_back(new Test());

Then I tried to just remove node from list like this:

Test remove_key(1);
tests_.remove_if([remove_key](const Test* p) { return remove_key == *p; });

It remove all nodes which value_ is 1, but remove_if call ::operator delete() so object in list are deleted. As I know, remove_if only remove from list but it would not delete object, but when I debug it, list call destructor of Test class, and delete the object by ::operator delete(_Ptr). What am I wrong?

(Below code is STL list remove_if callstack(reverse order) in Visual Studio 2013.)

list

remove_if(_Pr1 _Pred) {
    for (iterator _First = begin(); _First != end(); )
        if (_Pred(*_First))
            _First = erase(_First);
        else
            ++First;
}

iterator erase(const_iterator _Where) {
    _Nodeptr _Pnode = _Unlinknode(_Where++);
    this->_Freenode(_Pnode);
    return (_Makie_iter(_Where));
}

void _Freenode(_Nodeptr _Pnode) {
    this->_Getal().deallocate(_Pnode, 1);
}

void deallocate(pointer _Ptr, size_type _Count) {
    _Mybase::deallocate(_Ptr, _Count);
}

void deallocate(pointer _Ptr, size_type) {
    ::operator delete(_Ptr);
}
Abhijit
  • 62,056
  • 18
  • 131
  • 204
P-P
  • 1,670
  • 5
  • 18
  • 35
  • 1
    Where do you think the node goes after it is removed from the list? It doesn't delete the `Test` object the pointer points to, if that's what you are asking. – T.C. Apr 06 '15 at 10:50

2 Answers2

2

but when I debug it, list call destructor of Test class

No it doesn't. Rather your destructor is called because

  1. You have created a scoped variable remove_key , whose destructor would be called automatically when it will be scoped out
  2. Your lambda captured remove_key by value so when stack unwinding from the lambda, the destructor of remove_key would be called.

On a separate context, the code you highlighted is specifically for removing the node of the link list and not to remove the Test object.

So

void deallocate(pointer _Ptr, size_type) {
    ::operator delete(_Ptr);
}

deleted the node of the link list which stores a pointer to Test.

Abhijit
  • 62,056
  • 18
  • 131
  • 204
0

It deallocates the node of the list, not the object itself.

                Node
              +--------+    +------+
iterator -->  | Test* -+--> | Test |
              +--------+    +------+

Test will be unreachable if you delete a node.

If you have any particular reason to use dynamic allocation, then I recommend to use std::shared_ptr<Test>.

Inbae Jeong
  • 4,053
  • 25
  • 38