Утечка памяти в каком-то месте самодельного вектора

145
11 января 2019, 15:10

Сделал простенький вектор, все мои тесты проходит, но окаянное онлайн-тестирование кидает в меня ошибкой "Memory leak detected". Помогите найти места, где может быть утечка памяти. Я думаю, виноват pushBack, но все же в конце приложу полную версию кода, вдруг не он.

pushBack:

void PushBack(const T& value) {
        T* result;
        if (Array == nullptr) {
            result = new T[1];
            Array = result;
            end_ = Array + 1;
        }
        else if (arSize == (*this).Capacity()) {
            size_t capacity = (*this).Capacity() * 2;
            T* result = new T[capacity];

            for (unsigned int i = 0; i < arSize; ++i)
                result[i] = Array[i];
            Array = result;
            end_ = Array + capacity;
        }
        Array[arSize++] = value;
    }

Все имеющиеся переменные:

private:
T* Array;
T* end_;
unsigned int arSize = 0;

Весь код:

`template <typename T>
class SimpleVector {
public:
    SimpleVector() {
        Array = nullptr;
        end_ = Array;
    }
    explicit SimpleVector(size_t size) : Array(new T[size]), end_(Array + size){
        arSize += size;
    }
    ~SimpleVector() {
        delete[] Array;
    }
    T& operator[](size_t index) {
        return Array[index];
    }
    T* begin() {
        return Array;
    }
    T* end() {
        return end_;
    }
    size_t Size() const {
        return arSize;
    }
    size_t Capacity() const {
        return end_ - Array;
    }
    void PushBack(const T& value) {
        T* result;
        if (Array == nullptr) {
            result = new T[1];
            Array = result;
            end_ = Array + 1;
        }
        else if (arSize == (*this).Capacity()) {
            size_t capacity = (*this).Capacity() * 2;
            T* result = new T[capacity];

            for (unsigned int i = 0; i < arSize; ++i)
                result[i] = Array[i];
            Array = result;
            end_ = Array + capacity;
        }
        Array[arSize++] = value;
    }
private:
    T* Array;
    T* end_;
    unsigned int arSize = 0;
};`
Answer 1

Проще всего в таких случаях использовать профайлер. Я взял ваш код, в main() создал экземляр SimpleVector<int>, добавил несколько вызовов PushBack и прогнал через свой Deleaker.

Вот что получилось:

Строка 46, это вот тут:

void PushBack(const T& value) {
    T* result;
    if (Array == nullptr) {
        result = new T[1];

52-я - вот эта:

  else if (arSize == (*this).Capacity()) {
        size_t capacity = (*this).Capacity() * 2;
      T* result = new T[capacity];

Ошибка в том, что когда выделяется память под новый массив большего размера, память, выделенная под старый массив, не освобождается после копирования старых элементов в новый массив.

Ещё один момент, который мне кажется не очень правильным, это политика увеличения размера - он удваивается. Не будет ли слишком большим рост? Традиционно применяют линейный рост.

READ ALSO
Вывод русского тексты с помощью SDL_ttf

Вывод русского тексты с помощью SDL_ttf

С латиницей проблем нет, все работает как надо, но вместо кириллицы совершенно другие символыВот код, если это поможет

194
В чем ошибка? Можно ли вообще использовать такую структуру кода?

В чем ошибка? Можно ли вообще использовать такую структуру кода?

Самостоятельно обучаюсь программированиюСейчас пытаюсь решить задачу, найденную в интернете

202
создание dll в codeblocks

создание dll в codeblocks

Всем приветСоздаю dll в codeblocks, имею структуру проекта main

188
Не читается второй раз getline

Не читается второй раз getline

Появилась проблема с getline(file, string)Я хочу, чтобы с помощью этой программы было сначала высчитано количество строк в файле, а потом уже эти строки...

146