Kevin Laity
Kevin Laity

Reputation: 2481

Determining whether an object is in a std::set

I'm trying to determine whether an object is already contained within a std::set. According to msdn (and other sources) the set::find function is supposed to return end() if it doesn't find the element you asked for.

However when I implement code like the following, set::find returns junk (0xbaadf00d) instead.

set<Cell*> cellSet;

Cell* cell = new Cell();    

if (cellSet.find(cell) == cellSet.end())
{
    ...
}

Am I using this correctly? I'm working in Visual C++ 2005.

Upvotes: 3

Views: 2939

Answers (5)

David Schmitt
David Schmitt

Reputation: 59316

Your code as posted will always execute the code within the if, and 0xbaadf00d is the implementation's "one-past-the-end" marker.

Upvotes: 10

Loki Astari
Loki Astari

Reputation: 264381

One simple mistake is that you should be testing for not equal to end.

set<Cell*> cellSet;
Cell* cell = new Cell();
if (cellSet.find(cell) != cellSet.end())     // Test NOT EQUAL to end
{
     // Found item in set.
}

But also you should note that you are not comparing the actual Cell values but the pointer to Cell objects (which may or may not be what you wanted). Normally in C++ you don't tend to store pointers in containers as there is no implied ownership of the pointer but somtimes that is OK.

To actually compare objects you need to use the find_if() and pass a predicate (a functor).

struct PointerCellTest
{
    Cell&  m_lhs;
    PointerCellTest(Cell* lhs): m_lhs(lhs) {}
    bool operator()(Cell* rhs)
    {
         return lhs.<PLOP> == rhs.<PLOP>
    }
};


if(find_if(cellSet.begin(),cellSet.end(),PointerCellTest(cell)) != cellSet.end())
{
     // Found item in set.
}

Upvotes: 0

Alex B
Alex B

Reputation: 24926

When using stl set I like to use the count function to determine membership. I think this makes the code easier to read.

set<Cell*> cellSet;

Cell* cell = new Cell();    

if (cellSet.count(cell) == 0)
{
    ...
}

Upvotes: 5

j_random_hacker
j_random_hacker

Reputation: 51226

Try compiling and running just the code snippet you provided, and I guarantee you will find it executes without problems. The problem is almost certainly due to memory allocation bugs occurring elsewhere in your program, such as referencing an uninitialised pointer or a pointer to an object that has been deleted.

Are you familiar with how C++ containers manage their objects? They don't delete pointers for you. It is always safer to use containers of objects, rather than pointers to objects, when possible. (There are cases when containers of pointers are necessary -- in particular, when you want the container to store objects of different types from a single class hierarchy.)

Upvotes: 0

JaredPar
JaredPar

Reputation: 754585

Does callSet.end() have the value 0xbaadf00d as well?

EDIT

I ran this sample code in VS2008 and everything worked as expected. The find function returned an iterator pointing to the original value.

What behavior exactly are you seeing? Does it return end() or does it return another place in the set?

Upvotes: 1

Related Questions