1

My Blah class has code that creates a new Bling (a plain old data struct) and puts it into a std::vector:

Bling * const bling = new Bling;
m_Blings.push_back ( bling );

And the new Bling is eventually freed in Blah's destructor:

try
{
    while ( m_Blings.size() > 0 )
    {
        Bling *bling = m_Blings.back();
        m_Blings.pop_back();
        try { delete bling; } catch ( ... ) {}
    }
}
catch (...)
{
}

Lint (specifically PC-lint) issues a warning 429 on the line allocating the new Bling, "Custodial pointer 'bling' has not been freed or returned".

I understand it might be difficult for Lint to recognize this, but I am freeing it (in the destructor). So I'd like to suppress this message. But I'd prefer not to have to individually suppress every single std::vector<...>::push_back that I do, so I searched for a better way. This search led me to the following Stack Overflow question:

How can I tell lint to track a custodial pointer to a vector?

In there, the suggestion is to add the following line to a .lnt file:

-sem(std::vector::push_back, custodial(1))

Basically meaning "std::vector takes custody of the pointer passed as the first parameter to its push_back function". This suggestion worked for at least two people in that thread, including the original questioner.

But I put it in my options.lnt, and it's not working for me. Moreover, I don't really understand why it would work in the first place. I understand that it would let Lint know "this little local bit of code is not responsible for freeing or returning this new object", but I don't understand why it would make lint know that the object is eventually actually freed elsewhere. That is, I don't see how lint could know that the "back" call in my destructor necessarily returns the object that I added to the vector via push_back, and therefore I don't see how lint could know that the "delete" I'm doing is on the object that I added.

So, does anyone know how this situation can be dealt with, other than "add a suppression comment each and every time you call std::vector::push_back (and similar functions, including on other std containers)"?

cafce25
  • 15,907
  • 4
  • 25
  • 31
Bob Vesterman
  • 1,127
  • 1
  • 11
  • 31
  • That's an interesting way of deleting the elements of a vector of pointers. Why not loop over it and call delete on each element? – juanchopanza Jul 21 '14 at 16:01
  • You mean the multiple try-catch thing? The outer one's because otherwise lint will complain that a destructor shouldn't be able to throw an exception, and it thinks that possibly "delete" might do so. The inner one is just so that if delete actually *does* throw an exception on one of the Blings, I'll still (at least try to) delete the remaining Blings. – Bob Vesterman Jul 21 '14 at 16:23
  • Oh, or if you mean "while size > 0" rather than "for iterator", no particular reason. – Bob Vesterman Jul 21 '14 at 16:24
  • Thinking back a little more, I think the idiom was originally part of a more generic "empty the container" routine, not necessarily called at destruction time, so you'd want to not only delete the elements but also remove them from the vector. – Bob Vesterman Jul 21 '14 at 16:45

0 Answers0