LKB
LKB

Reputation: 1040

C++: Issue with clearing a vector of objects

EDIT: It seems this is a problem with using memset on my struct, instead clearing the vector. Thanks to all that have provided advice!


I'm attempting to clear my vector of Subject objects (my own defined class) called people. The vector sits in a struct (pQA) and is defined as the following:

typedef struct _FSTRUCT_
{
    const char * filePath;
    std::vector<Subject> people;
    long srcImageWidth;
    long srcImageHeight;
    STRUCT_CONFIG_PARAMS * configParam;
    unsigned char * imageBuf;
    int imageBufLen;
} STRUCT_FSTRUCT;

I am creating the pQA struct by:

STRUCT_FSTRUCT *pQA = NULL;
pQA = new STRUCT_FSTRUCT();
memset(pQA,0,sizeof(STRUCT_FSTRUCT));

I populate 'people' with data by using the Subject class' set methods. This is all fine. What I am wanting to do is then reset 'people', i.e. clear out all data and set the size to 0. I call the below method:

int ResetFaceCollection()
{
    if (!pQA->people.empty())
    {
        pQA->people.clear();
    }
}

The clear() line throws a debug assertion failed error message which states "Expression: vector iterators incompatible".

I'm not sure if this has anything to do with Subject's destructor:

Subject::~Subject(void)
{
}

I'm not using any pointers, so from what I've gathered, the destructor looks OK. I have, of course, defined the destructor in my .h file also ~Subject(void);.

I'm a bit lost as to why this is happening. Can anyone provide some insight?

I apologize if I'm omitted any necessary code, can update upon request!

Upvotes: 2

Views: 145

Answers (2)

Rupesh Yadav.
Rupesh Yadav.

Reputation: 904

Note: firtly OPs didn't showed that he is using memset some where in his code that's y i gave this answer, as i thought this weired behavior is because of some problem in clear as mentioned in below links.

1) cppreference.com: says that it Invalidates any references, pointers, or iterators referring to contained elements. May invalidate any past-the-end iterators. Leaves the capacity() of the vector unchanged.

2) cplusplus.com says that : A reallocation is not guaranteed to happen, and the vector capacity is not guaranteed to change due to calling this function. A typical alternative that forces a reallocation is to use swap :

vector<T>().swap(x); // clear x reallocating

but you can use this also:

int ResetFaceCollection()
{
    if (!pQA->people.empty())
    {
        pQA->people.erase(pQA->people.begin(),pQA->people.end());
    }
}

And check if it is giving any error?

here is the probably same environment and working fine with g++, clang, VC++ link

Upvotes: 1

milleniumbug
milleniumbug

Reputation: 15834

Your std::memset call is (a) redundant, as

pQA = new STRUCT_SPID_QA(); // <---- note the parens

value-initializes the object, which initializes integers to 0 and pointers to nullptr here.

and (b) actually very wrong:

If the object is not trivially-copyable (e.g., scalar, array, or a C-compatible struct), the behavior is undefined.

Source

Your _SPID_FQA_ contains non trivially copyable object of type std::vector<Subject>, which makes _SPID_FQA_ non trivially copyable.

Upvotes: 3

Related Questions