如何实现向量重新分配?

时间:2018-03-28 05:41:52

标签: c++ vector stl

我正在尝试实现我自己的C ++向量版本,但是当大小等于容量时,我的重新分配功能出现问题。具体来说,当调试器到达删除行时,我收到一个堆损坏错误,指出应用程序在堆缓冲区结束后写入内存。有人可以就我的方法错误提出建议吗?如果有任何其他信息有助于解决此问题,请与我们联系。

编辑:我添加了所有当前代码,以便其他人可以测试程序并重现问题。

标题文件:

#ifndef VECTOR_H
#define VECTOR_H

template <class ItemType> class Vector{
    public:
        Vector();
        Vector(int capacity);
        int size();
        int capacity();
        bool is_empty();
        ItemType at(int index);
        void push(ItemType newItem);
        void printItems();
        ~Vector();

    private:
        int m_capacity; // number of items we can hold
        int m_size; // current number of items
        int m_unitSize; // size of one unit (used for arithmetic in indexing)
        ItemType* m_vectorPtr; // pointer to actual vector
        void reallocate(); // reallocates memory if array is filled

};

#endif

实施和测试:

#include <iostream>
#include "Vector.h"
#include <assert.h>

// default constructor
template <class ItemType>
Vector<ItemType>::Vector()
:m_capacity(0), m_size(0) {
    m_unitSize = sizeof(ItemType);
    m_vectorPtr = nullptr;
}

// constructor with given number of items
template <class ItemType>
Vector<ItemType>::Vector(int capacity)
:m_size(0){
    int x = 1;
    while (x <= capacity) {
        x *= 2;
    }
    m_unitSize = sizeof(ItemType);
    m_capacity = x;
    m_vectorPtr = new ItemType[capacity];
}

// return total possible items
template <class ItemType>
int Vector<ItemType>::capacity() {
    return m_capacity;
}

// return current number of elements
template <class ItemType>
int Vector<ItemType>::size() {
    return m_size;
}

// return whether the vector is currently empty
template <class ItemType>
bool Vector<ItemType>::is_empty() {
    return m_size == 0;
}

// return the item at a given index
template<class ItemType>
ItemType Vector<ItemType>::at(int index) {
    return m_vectorPtr[index];
}

// reallocate the array if it becomes full
template <class ItemType>
void Vector<ItemType>::reallocate() {
    if (m_size >= m_capacity) {
        // allocate a new array twice the capacity
        m_capacity *= 2;
        ItemType* newVector = new ItemType[m_capacity];
        for (int i = 0; i < m_size; i++) {
            newVector[i] = m_vectorPtr[i];
        }
        delete[] m_vectorPtr;
        m_vectorPtr = newVector;
    }
}

// push an item onto the vector at the end
template<class ItemType>
void Vector<ItemType>::push(ItemType newItem) {
    if (m_size >= m_capacity) {
        // reallocate memory for the vector
        reallocate();
    }
    // push new item onto vector
    m_vectorPtr[m_size] = newItem;
    m_size++;
}

template <class ItemType>
void Vector<ItemType>::printItems() {
    for (int i = 0; i < m_size; i++) {
        std::cout << m_vectorPtr[i] << " ";
    }
    std::cout << std::endl;
}

template <class ItemType>
Vector<ItemType>::~Vector() {
    delete[] m_vectorPtr;
}

// test here
int main() { 

    // initialize a vector
    int startingCapacity = 3;

    Vector<int> testVector(startingCapacity);

    assert(testVector.capacity() == 4 &&
           testVector.size() == 0 &&
           testVector.is_empty() == true);

    // add two items to the vector
    testVector.push(3);
    testVector.push(7);

    assert(testVector.capacity() == 4 &&
           testVector.size() == 2 &&
           testVector.is_empty() == false);

    // print the two items
    testVector.printItems();

    // add past capacity to test reallocate
    testVector.push(5);
    testVector.push(8);
    testVector.push(6);

    assert(testVector.capacity() == 8 &&
        testVector.size() == 5 &&
        testVector.is_empty() == false);

    testVector.printItems();

    std::cout << "All test cases passed." << std::endl;

    return 0;
}

1 个答案:

答案 0 :(得分:2)

您必须在更改m_size之前重新分配,因为如果for m_size > m_capacity循环不正确,您将访问m_vectorPtr超过其大小的(m_capacity *= 2) > new_size。并确保新容量足够大template <class ItemType> void Vector<ItemType>::reallocate(size_t new_size) { if (new_size > m_capacity) { // allocate a new array twice the capacity if (m_capacity == 0) m_capacity = 10; while (m_capacity < new_size) m_capacity *= 2; ItemType* newVector = new ItemType[m_capacity]; for (int i = 0; i < m_size; i++) { newVector[i] = m_vectorPtr[i]; } delete[] m_vectorPtr; m_vectorPtr = newVector; } }

push_back

此处示例m_size方法在更改void push_back(ItemType item) { reallocate(m_size + 1); m_vectorPtr[m_size] = item; m_size++; }

之前重新分配
m_vectorPtr = new ItemType[capacity];

Demo

更新

构造函数 NOT

中有一个小错误
m_vectorPtr = new ItemType[m_capacity];

capacity

因为compileSdkVersion 'Google Inc.:Google APIs:24' 是请求的,而不是你想要的2的力量(3,而不是测试中的4)。