Advertisement

Getting address of Class instance in a Vector

Started by October 21, 2024 10:09 PM
4 comments, last by frob 1 day, 1 hour ago

Hi Guys,

How do I go about getting the address of Class instance in a Vector?

I am creating an object like below;

Object*     ObjectCreate()
{
    _objectID++;
    Object ObjectTemp(_objectID);
    _objectVector.push_back(ObjectTemp);

    for (std::vector<Object>::iterator it = _objectVector.begin(); it != _objectVector.end(); ++it)
    {
        if (it->id == _objectID)
        {
            it->x = 55;
            return &ObjectTemp;
        }
    }

    return 0;
}

But I believe I am returning the address of the temp object and not the one I am pushing on the vector.

So when I test the code (as per below), I am getting garbage values for ‘x’ instead of ‘7’ (or ‘55’ as per the create function.

    Object* obj = ObjectCreate();

    obj->x = 7;

    std::cout << "Object: " << obj->id << "\r\n";
    std::cout << "X: " << obj->x << "\r\n";

Many thanks for your help :D

I managed to get it working by doing the following.

Object*     ObjectCreate()
{
    _objectID++;
    Object ObjectTemp(_objectID);
    _objectVector.push_back(ObjectTemp);

    for (std::vector<Object>::iterator it = _objectVector.begin(); it != _objectVector.end(); ++it)
    {
        if (it->id == _objectID)
        {
            it->x = 55;
            return &_objectVector[_objectID - 1];
        }
    }

    return 0;
}

Although, I just realised that an object created this way will likely get its address corrupted when elements are removed or sorted.

Hmmm. Not sure what I can do to address that situation.

Advertisement

Actually this method isn't working well at all. In release mode it seems ok. But when you run it in debug the ‘id' value is inconsistent.

    Object* A = ObjectCreate();
    Object* B = ObjectCreate();
    Object* C = ObjectCreate();
    Object* D = ObjectCreate();
    
    std::cout << "A: " << A->id << "\r\n";
    std::cout << "B: " << B->id << "\r\n";
    std::cout << "C: " << C->id << "\r\n";
    std::cout << "D: " << D->id << "\r\n";

Which is returning this instead of the expected 1,2,3,4.

A: -572662307
B: -572662307
C: -572662307
D: 4

This has me baffled now.

Appears so far that STD::LIST is more suited to what I'm after here.

Moving to the For Beginners forum.

In keeping with For Beginners, I'll start with the direct answer: The easiest way is to take the address of an item is the indexed array form like : &myVector[0]; to get the address of item 0, or &myVector[n] for the address of item n.


For more on the subject:

It looks like you're learning about iterator invalidation. It's an essential subject to master.

It is critical to understand object lifetimes in software development. Objects are created, moved, and destroyed in specific ways, and if you break the rules around them you'll introduce bugs in the software. Here is a table with the simplified invalidation rules for the various standard library containers.

There are also tools out there like “smart pointers”, shared pointers are a way to distribute object ownership, weak pointers allow code to point to objects which can potentially have been destroyed so you can write code to safely handle it, unique pointers ensure only one copy of an object exists. Each have uses in managing object lifetimes. They solve a lot of problems around advanced object management and game engines do a lot of work around managing smart pointers.

And finally, you've got some example attempts where you are using iterators. Iterators are potentially complex objects, very powerful but the complexity can overwhelm beginners. It gets more complicated with iterators as there are some like output iterators that aren't meant for dereference, and there are the concept of indirectly readable and indirectly writable iterators. Dereferncing an iterator can also have concerns around chaining, as operator* and operator-> have potentially different behavior. In your example you'd get the address you asked about from simple dereference with *it but for more complex types that might get you something you didn't quite expect, like the address of an intermediate object in a chain.

Advertisement