我正在编写自己的
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 初始化数组?
您所显示的代码有很多问题。
为什么对数组使用
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;
}
}