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

时间:2014-09-19 23:50:19

标签: c++

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的元素数量,我没有收到错误消息。我没有正确管理我的记忆吗?

我不能在这个班级使用矢量。

2 个答案:

答案 0 :(得分:0)

您的以下行导致了您班级中几种方法的问题。

 arrayList = newArrayList;
   delete[] newArrayList;

应该是

delete[] arrayList;
arrayList = newArrayList;

当您扩大记忆时,首先应该是:

  1. 分配更大的记忆。
  2. 将现有块复制到更大的内存中。
  3. 使用主指针变量删除旧内存。
  4. 将新指针分配到主指针。
  5. 但理想情况下,如果可能,我们应该使用std::vector<T>而不是我们自己的。

答案 1 :(得分: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;  // <<-- 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)你现在拥有的数组中有多少项(即数组的大小()),以及

2)阵列可容纳的最大容量。

一旦你以这种方式重新实现,它就变得容易了。所有这些-1的东西都会让你失望,我甚至打赌会对堆腐败问题造成很大的麻烦。

此外,您的push_front函数应该从后面开始复制数组元素并将其工作到前面。例如:

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

这假定未超出capacity