尝试打印某些值时出现未处理的异常

问题描述 投票:0回答:1

我正在编写自己的

vector
实现,当我尝试打印数字时,有时我在尝试打印它的行上遇到异常。我知道问题出在内存中,但我不知道为什么当我用函数初始化内存时内存保持未初始化状态。

#include <iostream>
#include <memory>
#include <algorithm>
using namespace std;

template <typename T>
class badvector {
private:
    uint64_t _size;
    uint64_t _capacity;
    shared_ptr<T[]> arrptr;
    bool resizable;
    void initialize() {
        for (int i = 0; i < _size; i++) {
            arrptr[i] = 0;
        }
    }
    void initialize(uint64_t sz, shared_ptr<T[]> &ptrarr) {
        for (int i = 0; i < _size; i++) {
            ptrarr[i] = 0;
        }
    }
    void capacity_count() {
        _capacity = 0;
        for (int i = 0; i < _size; i++) {
            if (arrptr[i] != 0) {
                ++_capacity;
            }
        }
        if (_capacity > _size) {
            throw "error, capacity out of range";
        }
    }
public:
    explicit badvector() : _size(5), _capacity(0), arrptr(new T[5]), resizable(true) {
        initialize();
    }
    ~badvector() = default;
    uint64_t get_cp() {
        capacity_count(); 
        return this->_capacity;
    }
    uint64_t size() {
        return this->_size;
    }
    void push_back(T arg) {
        capacity_count();
        if (_capacity == _size) {
            resize(_size + 5);
        }
        arrptr[_capacity] = arg;
        ++this->_capacity; 
        capacity_count();
    }
    void reserve(uint64_t sz) {
        _size = sz;
        if (!resizable) {
            throw "Error, you are not able to reserve any more place, you used resize";
        }
        capacity_count();
        shared_ptr<T[]> temp(new T[sz]);
        initialize(sz, temp);
        for (int i = 0; i < _capacity; i++) {
            temp[i] = arrptr[i];
        }
        arrptr = temp;
        capacity_count();
    }
    void resize(uint64_t sz) {
        reserve(sz);
        resizable = false;
    }
    T operator[](uint64_t position) {
        capacity_count();
        if (position >= _capacity || position < 0) {
            throw "badvector out of range";
        };
        return *(arrptr.get() + position);
    }
    void print(uint64_t num) {
        capacity_count();
        if (num >= _capacity || num < 0) {
            throw "badvector out of range";
        }
        cout << arrptr[num] << endl;
    }
    const T* cbegin() const {
        return arrptr.get();
    }
    T* begin(){
        return arrptr.get();
    }
    const T* cend() const {
        return arrptr.get() + _size;
    }
    T* end() {
        return arrptr.get() + _size;
    }
};

int main() {
    badvector<int> b;
    b.reserve(30);
    cout << "size " << b.size() << endl << "capacity " << b.get_cp() << endl;
    for (int i = 0; i < 30; i++) {
        b.push_back(42);
    }
    cout << "size after push_back: " << b.size() << endl << "capacity after push_back: " << b.get_cp() << endl;
    for (auto i = b.begin(); i != b.end(); i++) {
        cout << b[*i] << endl;
    }
}

我真的不知道为什么会发生这种情况。可能其中一种变体是用 nullptr 初始化数组?

c++ arrays exception memory output
1个回答
0
投票

您所显示的代码有很多问题。

为什么对数组使用

shared_ptr
?您没有在类的实例之间共享它,如果您确实这样做了,您的代码将表现得非常糟糕。您应该使用
unique_ptr
来代替。

此外,在

main()
的最后一个循环中,您将向量的每个元素视为向量的索引,但事实并非如此。

但是,最重要的是,您似乎不理解 capacity (分配的元素数量)和 size (容量内使用的元素数量)之间的区别。您的

_capacity
成员无法准确反映您分配内存的元素数量。并且您在应该使用
_capacity
成员的地方使用了
_size
成员,反之亦然。

尝试更多类似这样的事情:

#include <iostream>
#include <memory>
#include <stdexcept>

using namespace std;

template <typename T>
class goodvector {
private:
    size_t _size;
    size_t _capacity;
    unique_ptr<T[]> arrptr;

public:
    goodvector() : _size(0), _capacity(5), arrptr(new T[5]) {
        for (size_t i = 0; i < _capacity; ++i) {
            arrptr[i] = T();
        }
    }

    ~goodvector() = default;

    goodvector(const goodvector&) = delete;
    goodvector(goodvector&&) = delete;
    goodvector& operator=(const goodvector&) = delete;
    goodvector& operator=(goodvector&&) = delete;

    size_t capacity() const {
        return _capacity;
    }

    size_t size() const {
        return _size;
    }

    void push_back(T arg) {
        if (_capacity == _size) {
            reserve(_size + 5);
        }
        arrptr[_size] = std::move(arg);
        ++_size; 
    }

    void reserve(size_t sz) {
        if (sz <= _capacity) return;
        unique_ptr<T[]> temp(new T[sz]);
        for (size_t i = 0; i < _size; ++i) {
            temp[i] = arrptr[i];
        }
        for (size_t i = _size; i < sz; ++i) {
            temp[i] = T();
        }
        arrptr = std::move(temp);
        _capacity = sz;
    }

    void resize(size_t sz) {
        if (sz < _size) {
            for(size_t i = sz; i < _size; ++i) {
                arrptr[i] = T();
            }
        }
        else if (sz > _size) {
            reserve(sz);
            for (size_t i = _size; i < sz; ++i) {
                arrptr[i] = T();
            }
        }
        _size = sz;
    }

    T operator[](size_t position) const {
        if (position >= _size) {
            throw out_of_range("out of range");
        }
        return arrptr[position];
    }

    void print(size_t position) const {
        if (position >= _size) {
            throw out_of_range("out of range");
        }
        cout << arrptr[position] << endl;
    }

    const T* cbegin() const {
        return arrptr.get();
    }

    T* begin() {
        return arrptr.get();
    }

    const T* cend() const {
        return arrptr.get() + _size;
    }

    T* end() {
        return arrptr.get() + _size;
    }
};

int main() {
    goodvector<int> b;
    b.reserve(30);
    cout << "size " << b.size() << endl << "capacity " << b.capacity() << endl;
    for (int i = 0; i < 30; ++i) {
        b.push_back(42);
    }
    cout << "size after push_back: " << b.size() << endl << "capacity after push_back: " << b.capacity() << endl;
    for (auto iter = b.begin(); iter != b.end(); ++iter) {
        cout << *iter << endl;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.