【问题标题】:if you increment an iterator assigned to a pointer, will the pointer hold the original memory location?如果增加分配给指针的迭代器,指针会保存原始内存位置吗?
【发布时间】:2015-12-24 23:00:04
【问题描述】:

我的代码不断崩溃,我相信这是因为当我在 Vector 类的插入函数中向后循环时,我将迭代器递减到原始指针变量之外。下面是插入函数:

iterator insert(iterator & iter, const Object& obj){
        if (theSize  >= theCapacity){
            resize(theSize+1);
            int *p = iter;
            for (iter; iter != this->end(); iter++){
                //cout << "test1" << endl;
            }
            for (iter; iter != p; iter--){
                *(iter-1) = *(iter-2);
                cout << "test1" << endl;
                //cout << *(iter - 2) << endl;
                //cout << *(iter - 1) << endl;
            }
        }
        else{
            int *p = iter;
            for (iter; iter != this->end(); iter++){
                cout << "test" << endl;
            }
            for (iter; iter != p; iter--){
                *(iter-1) = (*iter-2);
            }

        }
        *iter = obj;
        cout << theSize << endl << theCapacity << endl;
        //theSize++;
        return this->begin();
    }

插入函数的目标是将对象插入到迭代器位置,在我的代码中,我确保向量数组足够长,然后将数组中的每个对象移动到下一个索引空间;然后我将对象插入到迭代器指定的位置。

整个 Vector 类也是这样的:

#ifndef VECTOR_H
#define VECTOR_H

#include <algorithm>
#include <iostream>

template <typename Object>
class Vector
{
public:
    explicit Vector(int initSize = 0)
        : theSize{ initSize }, theCapacity{ initSize + SPARE_CAPACITY }
    {
        objects = new Object[theCapacity];
    }

    Vector(const Vector & rhs)
        : theSize{ rhs.theSize }, theCapacity{ rhs.theCapacity }, objects{ nullptr }
    {
        objects = new Object[theCapacity];
        for (int k = 0; k < theSize; ++k)
            objects[k] = rhs.objects[k];
    }

    Vector & operator= (const Vector & rhs)
    {
        Vector copy = rhs;
        std::swap(*this, copy);
        return *this;
    }

    ~Vector()
    {
        delete[] objects;
    }

    Vector(Vector && rhs)
        : theSize{ rhs.theSize }, theCapacity{ rhs.theCapacity }, objects{ rhs.objects }
    {
        rhs.objects = nullptr;
        rhs.theSize = 0;
        rhs.theCapacity = 0;
    }

    Vector & operator= (Vector && rhs)
    {
        std::swap(theSize, rhs.theSize);
        std::swap(theCapacity, rhs.theCapacity);
        std::swap(objects, rhs.objects);

        return *this;
    }

    bool empty() const
    {
        return size() == 0;
    }
    int size() const
    {
        return theSize;
    }
    int capacity() const
    {
        return theCapacity;
    }

    Object & operator[](int index)
    {
        return objects[index];
    }

    const Object & operator[](int index) const
    {
        return objects[index];
    }

    void resize(int newSize)
    {
        if (newSize > theCapacity)
            reserve(newSize * 2);
        theSize = newSize;
    }

    void reserve(int newCapacity)
    {
        if (newCapacity < theSize)
            return;

        Object *newArray = new Object[newCapacity];
        for (int k = 0; k < theSize; ++k)
            newArray[k] = std::move(objects[k]);

        theCapacity = newCapacity;
        std::swap(objects, newArray);
        delete[] newArray;
    }

    // Stacky stuff
    void push_back(const Object & x)
    {
        if (theSize == theCapacity)
            reserve(2 * theCapacity + 1);
        objects[theSize++] = x;
    }
    // Stacky stuff
    void push_back(Object && x)
    {
        if (theSize == theCapacity)
            reserve(2 * theCapacity + 1);
        objects[theSize++] = std::move(x);
    }

    void pop_back()
    {
        --theSize;
    }

    const Object & back() const
    {
        return objects[theSize - 1];
    }

    // Iterator stuff: not bounds checked
    typedef Object * iterator;
    typedef const Object * const_iterator;

    iterator begin()
    {
        return &objects[0];
    }
    const_iterator begin() const
    {
        return &objects[0];
    }
    iterator end()
    {
        return &objects[size()];
    }
    const_iterator end() const
    {
        return &objects[size()];
    }

    static const int SPARE_CAPACITY = 2;

    iterator insert(iterator & iter, const Object& obj){
        if (theSize  >= theCapacity){
            resize(theSize+1);
            int *p = iter;
            for (iter; iter != this->end(); iter++){
                //cout << "test1" << endl;
            }
            for (iter; iter != p; iter--){
                *(iter-1) = *(iter-2);
                cout << "test1" << endl;
                //cout << *(iter - 2) << endl;
                //cout << *(iter - 1) << endl;
            }
        }
        else{
            int *p = iter;
            for (iter; iter != this->end(); iter++){
                cout << "test" << endl;
            }
            for (iter; iter != p; iter--){
                *(iter-1) = (*iter-2);
            }

        }
        *iter = obj;
        cout << theSize << endl << theCapacity << endl;
        //theSize++;
        return this->begin();
    }
    iterator erase(iterator iter){

    }
    iterator find(iterator x, iterator y, const Object obj){

    }
private:
    int theSize;
    int theCapacity;
    Object * objects;
};

#endif

我的测试文件是这样的:

#include "Vector.h"
#include <iostream>
using namespace std;

int main(){
    Vector<int> input;
    Vector<int>::iterator iter;
    int data = 0;
    cout << "Enter five int digits: " << endl;
    for (int i = 0; i < 5; i++){
        cin >> data;
        input.push_back(data);
    }
    data = 7654;
    iter = input.begin();
    iter++;
    input.insert(iter, data);

    for (iter = input.begin(); iter != input.end(); iter++){
        cout << *iter << endl;
    }

    system("PAUSE");

}

【问题讨论】:

  • 调用resize 后,iter 不再有效。你已经释放了它曾经指向的内存。
  • Iter 是指向数组中由objects 指向的位置的指针。这个数组被 resize(theSize+1); 替换和删除,所以 iter 现在指向释放的内存,引用经典的话,“游戏结束!”。
  • 谢谢大家。有什么解决办法呢?
  • 我不确定这是否是问题所在,因为如果我调整大小(theSize)然后它会起作用,但最终会丢弃最后一个条目,因为大小==容量。
  • if i resize(theSize) then it works 因为resize(theSize) 是一个空操作——它什么都不做。

标签: c++ vector insert


【解决方案1】:

感谢 user4581301 和 Igor 的 cmets,我能够解决它。在调整数组大小时,您必须在迭代器丢失之前找到它的索引。调整大小后,将迭代器设置为索引处对象的内存地址。像这样:

if (theSize  >= theCapacity){
            int index = iter - this->begin();
            resize(theSize+1);
            iter = &objects[index];
            int *p = iter;

【讨论】:

    猜你喜欢
    • 2021-04-15
    • 2021-04-13
    • 1970-01-01
    • 2020-04-05
    • 1970-01-01
    • 2011-01-16
    • 1970-01-01
    • 1970-01-01
    • 2021-06-22
    相关资源
    最近更新 更多