简体   繁体   中英

something about new and delete[] in c++

I spent over 2 hours just debugging it and checking the error of code, but I still can not find the reason why it's crushing. If I delete the code between line 91 to line 93 , the source code runs in vs and vscode , but fails in dev-c . The feedback of dev-c is program received signal sigsegv . if not del, all platforms do not work? can someone tell me the reason and the solution? thanks.

#include <iostream>
using namespace std;
template <class T>
class DynamicVector
{
private:
    T *array;
    unsigned mallocSize, numofItems;
    int virtualZero;

public:
    DynamicVector(int Vindex)
    {
        array = NULL;
        numofItems = 0;
        mallocSize = 0;
        virtualZero = Vindex;
    }
    DynamicVector(const DynamicVector &another)
    {
        if (mallocSize < another.numofItems)
        {
            if (array)
            {
                delete[] array;
                array = NULL;
            }
            array = new T[another.mallocSize];
        }
        virtualZero = another.virtualZero;
        mallocSize = another.mallocSize;
        numofItems = another.numofItems;
        for (int i = 0; i < another.numofItems; i++)
            *(array + i) = *(another.array + i);
    }
    ~DynamicVector()
    {
        if (array)
        {
            delete[] array;
            array = NULL;
        }
    }
    DynamicVector<T> &operator=(const DynamicVector<T> &another)
    {
        if (mallocSize < another.mallocSize)
        {
            delete[] array;
            array = NULL;
            array = new T[another.mallocSize];
        }
        virtualZero = another.virtualZero;
        mallocSize = another.mallocSize;
        numofItems = another.numofItems;
        for (int i = 0; i < another.numofItems; i++)
            *(array + i) = *(another.array + i);
        return *this;
    }
    inline void push_back(const T &n)
    {
        if (numofItems < mallocSize)
        {
            *(array + numofItems) = n;
        }
        else if (numofItems == mallocSize)
        {
            T *num = new T[numofItems + 1];
            for (int i = 0; i < numofItems; i++)
                *(num + i) = *(array + i);
            if (array)
            {
                delete[] array;
                array = NULL;
            }
            array = new T[2 * mallocSize + 1];
            mallocSize = 2 * mallocSize + 1;
            for (int i = 0; i < numofItems; i++)
                *(array + i) = *(num + i);
            *(array + numofItems) = n;
            delete[] num;
            num = NULL;
        }
        numofItems++;
    }
    void push_back(const DynamicVector<T> &another)
    {
        T *num = new T[numofItems + 1];
        for (int i = 0; i < numofItems; i++)
            *(num + i) = *(array + i);
        if (array)
91        {
92            delete[] array;
            array = NULL;
        }
        array = new T[mallocSize + another.mallocSize];
        mallocSize = mallocSize + another.mallocSize;
        for (int i = 0; i < numofItems; i++)
            *(array + i) = *(num + i);
        delete[] num;
        num = NULL;
        for (int i = numofItems, j = 0; i < numofItems + another.numofItems; i++, j++)
            *(array + i) = *(another.array + j);
        numofItems = numofItems + another.numofItems;
    }
    T &operator[](int Vindex)
    {
        int _entry = Vindex - virtualZero;
        if (_entry < 0 || _entry >= numofItems)
        {
            cout << endl
                 << "Out Of Range";
            exit(1);
        }
        return array[_entry];
    }

    bool operator==(const DynamicVector<T> &dv) const
    {
        if (virtualZero == dv.virtualZero)
        {
            for (int i = 0; i < numofItems; i++)
                if (*(array + i) != *(dv.array + i))
                    return false;
            return true;
        }
        else
            return false;
    }
    unsigned length() const
    {
        return numofItems;
    }
    unsigned capacity() const
    {
        return mallocSize;
    }
    int firstIndex() const
    {
        return virtualZero;
    }
};
int main()
{

    DynamicVector<int> ra(-2);
    int i, n;
    cin >> n;
    ra.push_back(-3);
    ra.push_back(-2);
    ra.push_back(-1);
    for (i = 0; i < n; i++)
    {
        ra.push_back(i);
    }
    cout << "\n malloSize is " << ra.capacity();
    cout << "\n numofItems is " << ra.length();
    cout << "\n StartIndex is " << ra.firstIndex() << endl;
    for (i = -2; i < n + 1; i++)
    {
        cout << ra[i] << " ";
    }
    cout << endl;
    DynamicVector<int> raCopy(ra);
    cout << "\n malloSize is " << raCopy.capacity();
    cout << "\n numofItems is " << raCopy.length();
    cout << "\n StartIndex is " << raCopy.firstIndex() << endl;
    cout << endl;
    for (i = -2; i < n + 1; i++)
    {
        cout << ++ra[i] << " ";
    }
    cout << endl;
    for (i = -2; i < n + 1; i++)
    {
        cout << raCopy[i] << " ";
    }

    raCopy = ra;
    if (ra == raCopy)
        cout << "\n ra == raCopy";
    else
        cout << "\n ra != raCopy";

    ra[-2] = 100;

    if (ra == raCopy)
        cout << "\n ra == raCopy";
    else
        cout << "\n ra != raCopy";

    raCopy.push_back(ra);
    cout << endl;
    int firstI = raCopy.firstIndex();
    for (i = 0; i < raCopy.length(); i++)
    {
        cout << raCopy[i + firstI] << " ";
    }
    system("pause");
    return 0;
}

You are reading from uninitialized member variables in copy constructor:

    DynamicVector(const DynamicVector &another)
    {
        if (mallocSize < another.numofItems)
        {
            if (array)
            {
                delete[] array;
                array = NULL;
                }
            array = new T[another.mallocSize];
        }
        ...

Here mallocSize and array members are not initialized and contain random garbage, so the checks have could do anything. You have three senarios.

  1. mallocSize is randomly small thus:
    array is not initialized and points to random memory.
    Thus line 91 will cause a sigfault when eventually called.
  2. mallocSize is randoly large and array is not null.
    You call delete on random value thus corrupting your memory. Either causing a segfault or messing up memory so the line 91 does.
  3. mallocSize is randomly large and array is randomly null.
    It works (1 in three chance).

Should be just

    DynamicVector(const DynamicVector &another)
    {
        array = new T[another.mallocSize];
        ...

Also, everywhere in the code you can write array[i] instead of *(array + i) , eg array[i] = another.array[i] instead of *(array + i) = *(another.array + i) .

PS. Once you have it working get it code reviewed.

https://codereview.stackexchange.com/

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