Search code examples
c++stlstddeque

deque push back default constructor not called


I implemented a class following the rule of three, and I am getting a crash. Upon debugging I have came to the conclusion that in the copy constructor line number 51, the pointer oQueue is not NULL due to some internal logic of deque and hence the constructor tries to delete the memory and fails.

I then read somewhere that I should not check for NULLness of oQueue in copy constructor because it might not be initialized in the constructor. Should not oQueue be always initialized to NULL due to the default constructor?

    #include <iostream>
    #include <deque>
    #include <cstdlib>
    #define LENGTH 128

    typedef struct tDataStruct
    {

    char strA[LENGTH];

    char strB[LENGTH];
    int nNumberOfSignals;
    double* oQueue;

    tDataStruct()
    {
        nNumberOfSignals = 0;
        oQueue = NULL;
        memset(strA, 0, LENGTH);
        memset(strB, 0, LENGTH);
    }

    ~tDataStruct()
    {
        if (NULL != oQueue)
        {
            delete[] oQueue;
            oQueue = NULL;
        }
    }

    tDataStruct(const tDataStruct& other) // copy constructor
    {
        if (this != &other)
        {
            *this = other;
        }

    }
    tDataStruct& operator=(const tDataStruct& other) // copy assignment
    {
        if (this == &other)
        {
            return *this;
        }
        strncpy_s(strA, other.strA, LENGTH);
        strncpy_s(strB, other.strB, LENGTH);
        nNumberOfSignals = other.nNumberOfSignals;
        if (NULL != oQueue)
        {
            delete[] oQueue;
            oQueue = NULL;
        }
        if (other.nNumberOfSignals > 0)
        {
            //memcpy(oQueue, other.oQueue, nNumberOfSignals);
        }
        return *this;
    }
    } tDataStruct;


    int main()
    {
        tDataStruct tData;

        std::deque<tDataStruct> fifo;

        fifo.push_back(tData);
    }

Solution

  • Your implementation of the copy constructor invokes undefined behavior since the member variables of the object being constructed have not been initialized.

    You can use the default constructor to initialize the member variables first to get predictable behavior.

    tDataStruct(const tDataStruct& other) : tDataStruct()
    {
       *this = other;
    }