使用动态数组的 C++ 逻辑错误

Posted

技术标签:

【中文标题】使用动态数组的 C++ 逻辑错误【英文标题】:C++ logical error with using dynamic arrays 【发布时间】:2018-09-14 13:23:18 【问题描述】:

insert 函数中,我对数组 ditemstempItems 使用动态内存分配。

我使用 tempItems 作为一个数组,是 ditems 的两倍,并且还临时存储 ditems 中的所有项目;然后删除并分配 ditems 等于 tempItems

代码符合要求,但是当使用足够的数据进行测试时,需要 ditems 来存储 2000 个元素,似乎 ditems 数组并没有变得更大。但是如果我在构造函数中设置(arrayCap=2001;),那么没有问题。

我不熟悉使用动态数组并使用动态数组查看其他代码,看起来我没有犯任何错误。我不能在这个任务中使用向量,所以我被动态数组困住了,但我不确定这里出了什么问题。

template <class T>
class Vector 
    public:
        typedef T* iterator;
        Vector ()  
            arrayCap=1000;
            ditems = new T[arrayCap];
        

        T& operator[](unsigned int i) 
           return ditems[i];
        

        iterator begin () 
            used=0;
            return &ditems[used];
        
        iterator end ()  
            return &ditems[used];
        
        int size ()  return used; 
        void deletes()

            used--;

        

        iterator insert (iterator position, const T& item)  

            if(arrayCap-used<100)
            
                temp=arrayCap;
                arrayCap=2*arrayCap;

                tempItems=new T[arrayCap];
                for(int i=0; i<temp;i++)
                
                    tempItems[i]= ditems[i];
                
                delete [] ditems;
               ditems=tempItems;  
            

            for(Vector<T>::iterator i=&ditems[arrayCap-1]; i>position; i--)
            
               *i=*(i-1);
            
            used++;
            *position= item;
            return position;
        
    private:
        int arrayCap,temp;
        T *ditems;
        T *tempItems;
        int used;

;

【问题讨论】:

您的 begin()end() 返回相同的内容。您的范围将始终显示为空。 tempItems 应该是 insert 方法中的局部变量。没有理由将其设为类变量。 temp 变量也是如此。 used 变量的使用不正确,应该在构造函数中设置,而不是在begin 方法中设置。 begin 方法应该是 return &amp;ditems[0]; @FrançoisAndrieux 不是在这种情况下,在我的代码的其他部分未包括在这里,我只调用一次 begin() 每次创建一个对象,所以当我将更多元素插入到ditems中时使用会增加。 @StackUser 当您调用 begin 方法时,您将 used 设置为零。换句话说,调用 begin 会将向量的大小设置为零。显然这是一个错误。 【参考方案1】:

将数组移动到新位置会使迭代器position 无效,它指向旧数组。所以i&gt;position 是未定义的行为。

您应该在移动数组之前计算索引并将position设置为新数组中的索引。

template <class T>
class Vector 
    public:
        typedef T* iterator;
        Vector ()  
            arrayCap=1000;
            ditems = new T[arrayCap];
            used = 0;
        

        T& operator[](unsigned int i) 
           return ditems[i];
        

        iterator begin () 
            return ditems;
        
        iterator end ()  
            return &ditems[used];
        
        int size ()  return used; 
        void deletes()
            used--;
        

        iterator insert (iterator position, const T& item)  

            if(arrayCap-used<100)
            
                auto temp=arrayCap;
                arrayCap*=2;
                auto index = position - ditems;

                auto tempItems=new T[arrayCap];
                for(int i=0; i<temp;i++)
                
                    tempItems[i]= ditems[i];
                
                delete [] ditems;
                ditems = tempItems;
                position = ditems + index;
            

            for(Vector<T>::iterator i=&ditems[arrayCap-1]; i>position; i--)
            
               *i=*(i-1);
            
            used++;
            *position = item;
            return position;
        
    private:
        int arrayCap;
        T *ditems;
        int used;
;

【讨论】:

我在数组通过该循环之前更改了数组,所以它不应该指向新的 ditems 数组 ditems 将指向新数组,但 position(函数参数)不会。 我想我有点理解,但是我如何让 position 指向新数组 ditems int index = position - ditems; 在移动阵列之前和之后position = ditems + index;。我在答案中添加了编辑后的代码 sn-p。

以上是关于使用动态数组的 C++ 逻辑错误的主要内容,如果未能解决你的问题,请参考以下文章

C++ 作业 - 使用动态数组重载 >> 运算符

为啥大型静态数组会产生段错误而动态却不会? (C++)

C++ 动态数组每次添加都会将大小增加 1 - 错误

二维数组C++的动态分配

使用VBA根据逻辑动态循环数组元素

内存堆问题 C++,动态分配多维数组