Тема: Задача,Динамічні масиви,Основи ООП

Намагався попрактикуватись в класах в поєднанні з динамічною памʼяттю.На одній з перевірок на сайті https://algotester.com/ , виникає помилка часу виконання,що свідчить про вихід за межі масиву.Не можу зрозуміти де помилка.

На цьому тесті,видає правильний резльтат,але при цьому помилку :

5

insert
0 3
1 2 3

erase
0 2

set
0 10

size

print


Завдання:

Ваше завдання - власноруч реалiзувати структуру даних "Динамiчний масив".
Ви отримаєте Q запитiв, кожен запит буде починатися зi слова-iдентифiкатора, пiсля якого
йдуть його аргументи.
Вам будуть поступати запити такого типу:

• Вставка:
Iдентифiкатор - insert
Ви отримуєте цiле число index елемента, на мiсце якого робити вставку.

Пiсля цього в наступному рядку рядку написане число N - розмiр масиву, який треба вста-
вити.

У третьому рядку N цiлих чисел - масив, який треба вставити на позицiю index.

• Видалення:
Iдентифiкатор - erase
Ви отримуєте 2 цiлих числа - index, iндекс елемента, з якого почати видалення та n -
кiлькiсть елементiв, яку треба видалити.

• Визначення розмiру:
Iдентифiкатор - size
Ви не отримуєте аргументiв.
Ви виводите кiлькiсть елементiв у динамiчному масивi.

• Визначення кiлькостi зарезервованої пам’ятi:
Iдентифiкатор - capacity
Ви не отримуєте аргументiв.
Ви виводите кiлькiсть зарезервованої пам’ятi у динамiчному масивi.
Ваша реалiзацiя динамiчного масиву має мати фактор росту (Growth factor) рiвний 2.

• Отримання значення i-го елементу
Iдентифiкатор - get
Ви отримуєте цiле число - index, iндекс елемента.

Ви виводите значення елемента за iндексом. Реалiзувати використовуючи перегрузку опе-
ратора []

• Модифiкацiя значення i-го елементу
Iдентифiкатор - set
Ви отримуєте 2 цiлих числа - iндекс елемента, який треба змiнити, та його нове значення.
Реалiзувати використовуючи перегрузку оператора []

• Вивiд динамiчного масиву на екран
Iдентифiкатор - print
Ви не отримуєте аргументiв.
Ви виводите усi елементи динамiчного масиву через пробiл.
Реалiзувати використовуючи перегрузку оператора <<

Вхiднi данi
Цiле число Q - кiлькiсть запитiв.
У наступних рядках Q запитiв у зазначеному в умовi форматi.


Вихiднi данi
Вiдповiдi на запити у зазначеному в умовi форматi.


Мій код:


#include <iostream>
using namespace std;

class DynamicArray
{
    public:
        void insert(int index,int newSize,int* arrInput)
        {
            int tempsize = size;
            size += newSize;
            
            if(size >= capacity)
            {
                while(size >= capacity)
                {
                    capacity *= 2;
                }
            }
            
            int *arrNew = new int[capacity];
            
            if(index == 0)
            {
                for(int i = 0;i < newSize;i++)
                {
                    arrNew[i] = arrInput[i];
                }
                for(int i = index+newSize;i < size;i++)
                {
                    arrNew[i] = arr[i - newSize];
                }
            }
            else
            {
                for(int i = 0;i < index;i++)
                {
                    arrNew[i] = arr[i];
                }
                for(int i = 0;i < newSize;i++)
                {
                    arrNew[i + index] = arrInput[i];
                }
                for(int i = newSize + index;i < size;i++)
                {
                    arrNew[i] = arr[i - newSize];
                }
            }
            int* temp;
            temp = arr;
            arr = arrNew;
            arrNew = temp;
            delete[] temp;
            

        }
        void erase(int index,int count)
        {
            size -= count;
            
            if(size > 0 && capacity > size*2)
            {
                while(capacity > size*2)
                {
                    capacity /= 2;
                }
            }
            else
            {
                capacity = 1;
            }
            
            int *arrNew = new int[capacity];

            for(int i = 0;i < index;i++)
            {
                arrNew[i] = arr[i];
            }
            for(int i = index;i < size;i++)
            {
                arrNew[i] = arr[i + count];
            }

            int* temp;
            temp = arr;
            arr = arrNew;
            arrNew = temp;
            delete[] temp;   
            
        }
        void print ()///////////////////////////////////////////////////////
        {
            if(size == 0)
            {
                cout<<0<<endl;
            }
            else
            {
                for(int i = 0;i < size;i++)
                {
                    cout << arr[i] << " ";
                }
                cout<<endl;
            }
        }
        void getCapacity()
        {
            cout << capacity << endl;
        }
        void getSize()
        {
            cout << size << endl;
        }
        int& operator [](int index)
        {
            return arr[index];
        }
        
        DynamicArray() 
        {
            arr = new int[capacity];
        }
        ~DynamicArray()
        {
            delete[] arr;
        }



    private:
        int *arr;
        int size = 0;
        int capacity = 1;
};

int main()
{
    DynamicArray dynamicArray;
    int q;
    cin >> q;
    while(q--)
    {
        string func_name;
        cin >> func_name;
        
        if(func_name == "insert")
        {
            int index,newSize;
            cin >> index >> newSize;
            int *arrInput = new int[newSize];
            for(int i = 0; i < newSize; i++)
            {
                cin >> arrInput[i];
            }
            dynamicArray.insert(index,newSize,arrInput);

        }
        else if(func_name == "erase")
        {
            int index,count;
            cin >> index >> count;
            dynamicArray.erase(index,count);
        }
        else if(func_name == "size")
        {
            dynamicArray.getSize();
        }
        else if(func_name == "capacity")
        {
            dynamicArray.getCapacity();
        }
        else if(func_name == "get")
        {
            int index;
            cin >> index;
            cout << dynamicArray[index] << endl;
        }
        else if(func_name == "set")
        {
            int index,newValue;
            cin >> index >> newValue;
            dynamicArray[index]=newValue;
        }
        else if(func_name == "print")
        {
            dynamicArray.print();
        }
    }
}

2

Re: Задача,Динамічні масиви,Основи ООП

        void erase(int index,int count)
        {
            size -= count;
            
            if(size > 0 && capacity > size*2)
            {
                while(capacity > size*2)
                {
                    capacity /= 2;
                }
            }
            else
            {
                capacity = 1;
            }

Після цього capacity буде гарантовано менше за size. Вам цього точно не треба.

3

Re: Задача,Динамічні масиви,Основи ООП

Ось так?

   if(capacity > size*2)
            {
                while(capacity > size*2)
                {
                    capacity /= 2;
                }
            }

4

Re: Задача,Динамічні масиви,Основи ООП

Підставте конкретні числа і спробуйте. Скажімо, capacity у вас 16, а size хочете зробити 5.

5

Re: Задача,Динамічні масиви,Основи ООП

Перевірив ,ось так справді не виходить

   if(capacity > size*2)
            {
                while(capacity > size*2)
                {
                    capacity /= 2;
                }
            }

Перевірив ще раз оце,зі всіма можливими варіантами якими міг придумати,помилок не бачив

            if(size > 0 && capacity > size*2)
            {
                while(capacity > size*2)
                {
                    capacity /= 2;
                }
            }
            else
            {
                capacity = 1;
            }

6 Востаннє редагувалося steamwater (02.03.2024 00:06:24)

Re: Задача,Динамічні масиви,Основи ООП

данічка, я не рекомендую вам знижувати capacity, принаймнi так агресивно. Загалом, його можна було б зовсiм не знижувати. Але це вже питання того, як буде використовуватись ваш вектор. I от ще що:

            int* temp;
            temp = arr;
            arr = arrNew;
            arrNew = temp;// Видалить цей рядок, бо в ньому нема потреби 
            delete[] temp;  

я спочатку трохи не розiбрав i написав:
бо пiсля наступного delete UB + memory leak
Нi, тут все безпечно. Але ця iнструкцiя непотрiбна i до того ж може заплутати)