我正在尝试a very noob way to implement vector作为练习。我编写了许多函数,并且看起来工作正常,但是当我尝试推入一系列值时,会导致输出结果超出预期。
我的类型定义是:
template <typename T, class Allocator = allocator<T>> class vector {
public:
// type definitions
using allocator_type = Allocator;
using value_type = T;
using reference = value_type &;
using const_reference = const value_type &;
using pointer = typename std::allocator_traits<Allocator>::pointer;
using const_pointer =
typename std::allocator_traits<Allocator>::const_pointer;
using iterator = value_type *;
using const_iterator = const value_type *;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = const std::reverse_iterator<const_iterator>;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
// member variables
allocator_type m_allocator;
T *m_data = nullptr;
size_type m_capacity = 10;
size_type m_size = 0;
...
和push_back()
函数是:
template <typename T, class Allocator>
constexpr void vector<T, Allocator>::push_back(const T &val_) {
m_data[m_size++] = val_;
if (m_size > capacity()) {
m_capacity = m_size * 2;
m_data = m_allocator.allocate(m_capacity);
}
}
当我尝试:
#include "vector.h"
#include <iostream>
int main() {
p1v0t::vector<int> iv;
for (int i = 0; i < 15; ++i) {
iv.push_back(i);
}
for (auto item : iv) {
std::cout << item << ' ';
}
}
它给出如下输出:
0 0 0 0 0 0 0 0 0 0 10 11 12 13 14
可能的原因是什么?任何因我愚蠢而大喊大叫的行为都可以接受...
答案 0 :(得分:4)
您在添加元素后测试容量:
m_data[m_size++] = val_;
if (m_size > capacity()) {
因此,如果m_size ==容量,则插入到末尾,然后才调整数据区域的大小。
由于初始容量为10,因此在插入第11个元素时,示例中首先遇到问题。然后m_size
== 10,capacity
== 10。
→您在val_
上插入m_data[10]
。
此外,您可能想检查如何使用分配器。使用通常的分配器,您需要在增加容量(并释放旧区域)之后将项目复制到新分配的区域。从您的帖子中我们无法确定,Allocator可能是您的定制商品,行为不规范。
答案 1 :(得分:3)
m_data = m_allocator.allocate(m_capacity);
这会分配新的内存,替换旧的指针,但是旧的指针及其数据将被丢弃(泄漏)。您需要同时具有新指针和旧指针,从旧指针复制到新指针,删除旧指针并将其替换为新指针。
如其他答案所述,您的容量增加是在错误的时间发生的;只需将支票移到新元素的分配之前,并对其进行调整以测试>=
而不是>
即可解决此问题。