кое-что о new и delete [] в c ++ - PullRequest
0 голосов
/ 06 мая 2020

Я потратил более 2 часов на то, чтобы просто отладить его и проверить код ошибки, но до сих пор не могу найти причину, по которой он ломается. Если я удалю код от line 91 до line 93, исходный код будет работать в vs и vscode, но не будет работать в dev-c. Обратная связь dev-c - program received signal sigsegv. если не дел, все платформы не работают? может кто-нибудь сказать мне причину и решение? спасибо.

#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;
}

1 Ответ

2 голосов
/ 06 мая 2020

Вы читаете из неинициализированных переменных-членов в конструкторе копирования:

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

Здесь члены mallocSize и array не инициализированы и содержат случайный мусор, поэтому проверки могут делать что угодно. У вас есть три сенара ios.

  1. mallocSize случайно мало, поэтому:
    array не инициализируется и указывает на случайную память.
    Таким образом, строка 91 вызовет sigfault когда в конечном итоге вызывается.
  2. mallocSize является произвольно большим, а array не является нулевым.
    Вы вызываете delete на случайное значение, таким образом разрушая вашу память. Либо вызывает segfault, либо вызывает беспорядок в памяти, поэтому строка 91.
  3. mallocSize имеет случайный размер, а array - случайное значение null.
    Это работает (вероятность 1 из трех).

Должно быть просто

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

Кроме того, везде в коде вы можете писать array[i] вместо *(array + i), например array[i] = another.array[i] вместо *(array + i) = *(another.array + i).

PS. Как только он заработает, проверьте его код.

https://codereview.stackexchange.com/

...