Не изменяется адрес указателя в массиве

Подскажите, пожалуйста, почему на 18-ой строчке указатель продолжает содержать в себе адрес на значение 10, если stack был переопределен в виде нового массива?


Ответы (1 шт):

Автор решения: NunOfIt

"oldstack" - это указатель на первое значение int в выделеной с помощью оператора new памяти, соответсвенно, если первым push-ем вы добавили в класс 10, то этот указатель на него и будет указывать. И я бы на вашем месте переписал этот класс, ибо создавать новый массив в куче, потом записывать туда значения из старого, каждый раз, когда вы удаляете или добавляете элемент очень непроизваодительно. Ладно, когда там 5-10 элементов, но а если там их например миллион...

#include <iostream>

class MyVector {
    int* _arr;
    size_t _size, _count;

    static constexpr size_t DEFAULT_SIZE = 8;

public:
    /* Constructors */

    MyVector(): MyVector(0) {}

    MyVector(size_t size) {
        _arr = nullptr;
        (void) _set(size, 0, 0);
    }

    MyVector(const MyVector& other) {
        _arr = nullptr;
        (void) _set(other);
    }

    MyVector(MyVector&& other) {
        _size = 0;
        _count = 0;
        _arr = nullptr;
        other.swap(*this);
    }

    /* Destructors */

    ~MyVector() { delete[] _arr; }

    /* Class Functions */

    void push_back(int val) {
        (void) _check_size_count();
        _arr[_count++] = val;
    }

    bool pop_back() {
        if(_count) {
            _arr[--_count] = 0;
            return true;
        }
        return false;
    }

    void insert(size_t idx, int val) {
        (void) _check_index(idx);
        (void) _check_size_count();

        for(size_t i = ++_count; i > idx; --i)
            _arr[i] = _arr[i - 1];
        _arr[idx] = val;
    }

    size_t pop(int val) {
        size_t shift = 0;
        for(size_t i = 0; i < _count; ++i)
            if(_arr[i] == val)
                ++shift;
            else if(shift)
                _arr[i - shift] = _arr[i];
        
        _count -= shift;
        for(size_t i = 0, j = _count; i < shift; ++i, ++j)
            _arr[j] = 0;
        return shift;
    }

    void resize(size_t new_size) {
        if(new_size < _count && new_size > _size)
            (void) reserve(new_size);
        _count = new_size;
    }

    void reserve(size_t new_capacity) {
        int* tmp = _arr;
        _size = new_capacity;
        if(new_capacity < _count)
            _count = new_capacity;

        _arr = nullptr;
        _arr = new int[new_capacity];

        size_t i = 0;
        for(; i < _count; ++i)
            _arr[i] = tmp[i];
        for(; i < _size; ++i)
            _arr[i] = 0;

        delete[] tmp;
    }

    size_t size() const { return _count; }
    size_t capacity() const { return _size; }

    int* begin() { return _arr; }
    int* end() { return _arr + _count; }

    void clear() { (void) _set(0, 0, 0); }

    void swap(MyVector& other) {
        std::swap(_arr, other._arr);
        std::swap(_size, other._size);
        std::swap(_count, other._count);
    }

    /* Operators */

    MyVector& operator=(const MyVector& other) {
        (void) _set(other);
        return *this;
    }

    MyVector& operator=(MyVector&& other) {
        MyVector temp;
        other.swap(temp);
        temp.swap(*this);
        return *this;
    }

    int& operator[](size_t idx) { return _arr[_check_index(idx)]; }
    const int& operator[](size_t idx) const { return _arr[_check_index(idx)]; }

    explicit operator bool() const { return bool(_size); }

    friend std::ostream& operator<<(std::ostream&, const MyVector&);

private:
    void _set(size_t size, size_t count, size_t null_start) {
        _size = size;
        _count = count;

        delete[] _arr;
        _arr = nullptr;

        if(!size) return;

        _arr = new int[size];
        for(size_t i = null_start; i < size; ++i)
            _arr[i] = 0;
    }

    void _set(const MyVector& other) {
        size_t count = other._count;
        (void) _set(other._size, count, count);

        for(size_t i = 0; i < count; ++i)
            _arr[i] = other._arr[i];
    }

    size_t& _check_index(size_t& idx) const {
        if(idx >= _count)
            throw std::invalid_argument("index out of range!");
        return idx;
    }

    void _check_size_count() {
        if(!_size)
            (void) _set(DEFAULT_SIZE, 0, 0);
        if(_size == _count)
            (void) reserve(2 * _size);
    }
};

std::ostream& operator<<(std::ostream& out, const MyVector& other) {
    out << '[';
    if(other) {
        out << other._arr[0];
        for(int i = 1; i < other._count; ++i)
            out << ", " << other._arr[i];
    }
    out << ']';
    return out;
}

int main() {
    MyVector mvec;
    mvec = std::move(MyVector(2));
    std::cout << mvec << '\n';

    mvec.push_back(5);
    mvec.push_back(-3);
    mvec.push_back(-3);
    std::cout << mvec << '\n';

    std::cout << "\nel1: " << mvec[1] << '\n';
    for(int& el: mvec)
        std::cout << el << ' ';
    std::cout << "\n\n";

    mvec.pop(-3);
    std::cout << mvec << '\n';
    mvec.insert(0, -3);
    std::cout << mvec << '\n';
    mvec.clear();
    std::cout << mvec << '\n';
    return 0;
}
→ Ссылка