Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Segmentation fault when push_back to vector c++

Tags:

c++

I am trying to append a blank object to a list using the push_back method.

main.cpp

    vector<FacialMemory> facial_memory;

    printf("2\n");

    // Add people face memories based on number of sections
    for (int i = 0; i < QuadrantDict::getMaxFaceAreas(); i++)
    {
            printf("i %d\n", i);
            FacialMemory n_fm;
            facial_memory.push_back(n_fm);  // NOTE: Breaks here
    }

At the push_back method call, the program crashes with a segmentation fault. I have looked around at similar questions and they point to the solution I have here. I have also tried to pass FacialMemory() into the push_back call but still the same issue.

The FacialMemory class is defined as such: FacialMemory.h

class FacialMemory
{
private:
        vector<FaceData> face_memory;
public:
        FacialMemory();
        ~FacialMemory();
        void pushData(FaceData face);
        bool isEmpty();
        vector<FaceData> getFaces();
        FaceData getRecent();
};

Constructor and destructor

FacialMemory::FacialMemory()
{
}


FacialMemory::~FacialMemory()
{
       delete[] & face_memory;
}
like image 887
DSchana Avatar asked Jan 18 '17 06:01

DSchana


1 Answers

When you push_back an item into a vector, the item is copied. Sometimes this triggers more work as the vector is resized: Its current contents are copied, and the now-copied elements that used to belong to the vector are destroyed. destruction invokes the destructor.

Unfortunately, FacialMemory's destructor contains a fatal error:

FacialMemory::~FacialMemory()
{
       delete[] & face_memory; <<== right here
}

It tries to delete[] data that was not allocated by new[], and whatever is managing the program's memory threw a fit because the expected book-keeping structures that keep track of dynamically allocated storage (memory allocated with new or with new[]) for the storage being returned were not found or not correct.

Further, face_memory is a std::vector, an object designed to look after its memory for you. You can create, copy, resize, and delete a vector without any intervention in most cases. The most notable counter case is a vector of pointers where you may have to release the pointed-at data when removing the pointer from the vector.

The solution is to do nothing in the FacialMemory class destructor. In fact, the Rule of Zero recommends that you not have a destructor at all because FacialMemory has no members or resources that require special handling. The compiler will generate the destructor for you with approximately zero chance of a mistake being made.

While reading the link for the Rule of Zero, pay attention to the Rules of Three and Five because they handle the cases where a class does require special handling and outline the minimum handling you should provide.

like image 191
user4581301 Avatar answered Sep 30 '22 18:09

user4581301