_block_type_is_valid(phead- nblockuse) 当使用 delete[] 时

_block_type_is_valid(phead- nblockuse) when using delete[]

本文关键字:delete nblockuse type block is valid phead-      更新时间:2023-10-16
template<typename T>
    class SDAL{
        private:
            int capacity;
            int tail;
            int head;
            T * arrayList;
        public:
            SDAL();
            SDAL(int capacity);
            ~SDAL();
            const T& replace(const T& t, int position);
            void insert(const T& t, int position);
            void push_back(const T& item);
            void push_front(const T& item);
            const T& remove(const int& position);
            const T& pop_back();
            const T& pop_front();
            const T& item_at(int position);
            bool isEmpty() const;
            int size() const;
            void clear();
            //bool contains(const T& t, equals function)
            void print() const;
    };
    template<typename T>
    SDAL<T>::SDAL(){
        this->capacity = 50;
        this->tail = -1;
        this->head = -1;
        arrayList = new T[capacity];
    }
    template<typename T>
    SDAL<T>::SDAL(int capacity){
        this->capacity = capacity;
        this->tail = -1;
        this->head = -1;
        arrayList = new T[capacity];
    }
    template<typename T>
    SDAL<T>::~SDAL(){
        delete[] arrayList;
    }
    template<typename T>
    int SDAL<T>::size() const{
        return (tail + 1);
    }
    template<typename T>
    bool SDAL<T>::isEmpty() const{
        return (tail == -1);
    }
    template<typename T>
    void SDAL<T>::push_back(const T& item){
        if (isEmpty()){
            arrayList[0] = item;
            tail = 0;
            head = 0;
        }
        else if (tail < capacity - 1){
            ++tail;
            arrayList[tail] = item;
        }
        else{
            int newCapacity = capacity * 1.5;
            T * newArrayList = new T[newCapacity];
            for (int i = 0; i <= tail; ++i){
                newArrayList[i] = arrayList[i];
            }
            ++tail;
            newArrayList[tail] = item;
            capacity = newCapacity;
            arrayList = newArrayList;
            delete[] newArrayList;
        }
    }
    template<typename T>
    void SDAL<T>::push_front(const T& item){
        if (isEmpty()){
            arrayList[0] = item;
            tail= 0;
            head = 0;
        }
        else if (tail < capacity){
            T *newArrayList = new T[capacity];
            newArrayList[head] = item;
            if (tail == 0){
                newArrayList[1] = arrayList[0];
            }
            else{
                for (int i = 0; i <= tail; ++i){
                    newArrayList[i+1] = arrayList[i];
                }
            }
            ++tail;
            arrayList = newArrayList;
        }
        else{
            int newCapacity = capacity * 1.5;
            T * newArrayList = new T[newCapacity];
            newArrayList[head] = item;
            for (int i = 0; i <= tail; ++i){
                newArrayList[i+1] = arrayList[i];
            }
            ++tail;
            capacity = newCapacity;
            arrayList = newArrayList;
            delete[] newArrayList;
        }
    }
    template<typename T>
    void SDAL<T>::print() const{
        for (int i = 0; i <= tail; ++i){
            cout << " " << arrayList[i];
        }
        cout << endl;
        cout << "Head = " << head << endl;
        cout << "Tail = " << tail << endl;
    }
int main() 
{
    SDAL<char> list(5);
    list.push_back('a');
    list.push_back('b');
    list.push_back('c');
    list.push_front('d');
    list.push_front('e');
    list.push_front('f');
    list.push_front('g');
    list.print();
    cout << list.size() << endl;
    return 0;
}

我已经尝试了一切,但我无法弄清楚为什么我会遇到这个问题。当我初始化我的数组时,我根据该容量的大小传入一个int容量,该数组是使用 arrayList = new T[capacity] 动态分配的。

程序执行后,析构函数被调用以delete[] arrayList。但是,当程序运行时,我收到错误_block_type_is_valid(phead- nblockuse)我不明白为什么会发生这种情况,请帮助!

如果我在初始化时增加容量的大小大于我尝试添加到arrayList的元素数量,则不会收到错误消息。我没有正确管理我的记忆吗?

我不能对这个类使用向量。

您的以下行在您的类的几个方法中导致了问题。

 arrayList = newArrayList;
   delete[] newArrayList;

它应该是

delete[] arrayList;
arrayList = newArrayList;

扩展内存时,首先应执行以下步骤:

  1. 分配更大的内存。
  2. 将现有块复制到更大的内存中。
  3. 使用主指针变量删除旧内存。
  4. 将新指针分配到主指针中。

但理想情况下,如果可能的话,我们应该使用std::vector<T>而不是我们自己的。

第一个明显的错误:

else if (tail < capacity)
{
    T *newArrayList = new T[capacity];
    newArrayList[head] = item;
    if (tail == 0)
        newArrayList[1] = arrayList[0];
    else
    {
        for (int i = 0; i <= tail; ++i)
            newArrayList[i + 1] = arrayList[i];
    }
    ++tail;
    arrayList = newArrayList;  // <<-- memory leak
}

在上面的代码中,您未能delete []原始arrayList,因此存在内存泄漏。

第二个错误:

    arrayList = newArrayList;  // <-- you copied allocated pointer here
    delete[] newArrayList;     // <-- now you've deleted it here!

您刚刚删除了分配的内存。 它应该是:

    delete [] arrayList;
    arrayList = newArrayList;  

还有更多的错误,比这,但这些是显而易见的。

另一件事是,您似乎无法确定您拥有的是链表,还是只是std::vector的重新发明。 为什么这里有headtail? 为什么不用两个简单的 int 成员变量来告诉你:

1(你现在数组中有多少个项目(即数组的size((,以及

2( 阵列可以容纳的最大容量。

一旦你以这种方式重新实现事情,它就会变得容易得多。 所有这些-1的东西都让你失望,我什至敢打赌,堆腐败问题引起了很多悲伤。

此外,您的push_front函数应该是从后面开始复制数组元素,然后一直复制到前面。 例如:

for (int i = tail - 1; i >= 0;  --i)
    arrayList[i+1] = arrayList[i];
arrayList[0] = item;

这假定尚未超过capacity