简体   繁体   中英

Vector iterators incompatible in assignment overload

Simple problem here. I'm dealing with a bit of an issue of assignment here with vectors. I have one class, Inventory:

class Inventory
{
public:
    __inline void operator=( const Inventory& rtSide )
    {
        items.clear();
        for(auto it=rtSide.items.begin(); it!=rtSide.items.end(); ++it)
        {
            items.push_back(*it);
        }
    }
private:
    std::vector<void*> items;
}

There's a struct that contains the class:

typedef struct
{
    Inventory *inventory;
} player_t;

Upon assigning/doing pointer math on a pointer of player_t, Inventory's = overload gets called, as you would expect. However, using MSVC, it would appear that there's an assertion failure, specifically, "vector iterators incompatible". The weird thing is, this happens on the clear(). I have no idea what's goin on here. If someone could give me some assistance that would be great.

Here's an example of what's going on. Using pointer math, we can determine the client number by subtracting the current client's player structure from the base:

clientNum = newcl - svs.clients;

This specifically is what is causing me to assert.

I'm pretty sure you want to copy the items from the rtSide list, not the ones in this .

    items.clear();
    for(auto it=rtSide.items.begin(); it!=rtSide.items.end(); ++it)
    {
        items.push_back(*it);
    }

(Of course, the compiler will generate this code for you if you don't write your own operator= , and you can also copy a vector by items = rtSide.items; - my point with the post was more to point out that "there is nothing wrong with your iterators, you are just not copying the right thing").

And I would also say that using a vector<void *> is pretty much "using C++ in a C way". You should store at least a pointer to a base-class, if not a smart pointer to a base-class. Baseclass could be something like "inventry_item" or something like that.

(And I believe xxxx_t types are reserved for POSIX, so you shouldn't really call your types xxxx_t )

I suspect that your pointer arithmetic resulted in attempting to call the assignment operator on an Inventory , but the pointer did not in fact point to an Inventory . (eg it may point to a delete 'd Inventory ) If that was the case, vector 's guts could be filled with random garbage, which could cause these kinds of assertion failures.

For instance, your the caller might do the moral equivalent of:

Inventory out;
Inventory* target = nullptr;
*target = out;

which could cause these kinds of assertion failures. Check the code calling the assignment operator.

(Also note that your assignment operator doesn't handle assignment to self; but in that case it will just clear the Inventory , not cause assertion failures)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM