【问题标题】:Why does deleting an allocated array cause a memory error?为什么删除分配的数组会导致内存错误?
【发布时间】:2019-12-16 00:04:49
【问题描述】:

我为教育目的实现了一个 ArrayList 类,但是在我的 expand() 方法中删除数组时遇到了内存错误。

这是我的课程和所有重要的方法:

//create array with default size 2
template<class T>
ArrayList<T>::ArrayList(){
    realSize = 2;
    count = 0;
    data = new T[realSize];
}

//destructor
template<class T>
ArrayList<T>::~ArrayList() {
    delete []data;
}

//adds value to end of list
template<class T>
void ArrayList<T>::add(T val) {
    //if reached end of array, expand array
    if (count >= realSize)
        expand();
    data[count] = val;
    count++;
}

//inserts value at index
template<class T>
void ArrayList<T>::insert(T val, int index) {
    if (!isValid(index)) return;
    //if index is greater than current size, expand
    while (index >= realSize || count >= realSize) {
        expand();
    }
    //shift values before index
    for (int i = count; i >= index; i--) {
        T val = data[i];
        data[i + 1] = data[i];
    }
    data[index] = val;
    count++;
}

//return value at index
template<class T>
T ArrayList<T>::get(int index) {
    if (!isValid(index)) return 0;
    return data[index];
}

template<class T>
int ArrayList<T>::size() {
    return count;
}

template<class T>
void ArrayList<T>::expand() {
    //double array size
    realSize = realSize * 2;
    T* newData = new T[realSize];
    //replace data
    for (int i = 0; i < count; i++) {
        newData[i] = data[i];
    }
    delete[]data; //<--ERROR OCCURS HERE
    data = newData;
}

这里是一些会导致错误的代码

    ArrayList<int>* list = new ArrayList<int>();

    list->add(1);
    list->add(5);
    list->insert(2, 1);
    list->insert(3, 2);
    list->insert(4, 3); //<---ERROR OCCURS HERE

错误是一个显示为

的消息框

调试错误!

程序: ...ommunity\Common7\IDE\Extensions\TestPlatorm\testhost.x86.exe

检测到堆损坏:在 0x05D69BC0 的正常块 (#296) 之后

CRT 检测到应用程序在堆缓冲区结束后写入内存。

为什么在调用expand方法时偶尔会报错?据我所知,当调用 expand() 时,数组的顺序是预期的(在我的示例中,它是 {1, 2, 3, 5})。

【问题讨论】:

  • 您的expand 函数存在不相关但更进一步的问题,例如在调用new[] 之前调整成员变量。如果new[] 抛出异常,则您现在有一个具有错误值的对象。
  • 感谢您的评论。我将翻转调整和内存分配以解决故障。

标签: c++ arrays memory allocation


【解决方案1】:

问题出在insert 方法中。当您复制现有元素为新元素腾出空间时,您从元素count 开始,然后将data[count] 向上复制一个槽位到data[count + 1]。但是,data[count] 中没有存储任何元素,并且在正确的情况下,对 data[count + 1] 的访问将超过为 data 分配的空间。

这些情况发生在第二个insert 呼叫中。 count 是 3,realsize 是 4,index 是 2,所以不会发生扩展。然后,您的 for 循环将分配 data[count + 1] = data[count],即 data[4] = data[3]。由于数据只有 4 个元素的空间,写入data[4] 会破坏已分配空间末尾的数据,这会在稍后的内存操作中检测到​​(在这种情况下,当通过调用delete 释放分配的空间时) )。

解决方案是在int i = count - 1 处开始循环,或在以下条件下递减:

for (int i = count; --i >= index; )

无关,T val = data[i]; 声明没有任何用处,可以删除。

【讨论】:

  • 哦,我明白了。所以这是一个栅栏错误,对吗?我没有意识到设置数据超出错误的大小可能会导致删除时出错!而且我也没有意识到我在设置范围之外的数据。你最后提到的那一行是我调试的尝试,因为我认为 insert() 方法可能存在问题,因为直到我开始使用它才出现错误。感谢您的帮助。
猜你喜欢
  • 2020-03-14
  • 1970-01-01
  • 2021-06-16
  • 1970-01-01
  • 2022-01-15
  • 2022-11-15
  • 1970-01-01
  • 1970-01-01
  • 2020-03-15
相关资源
最近更新 更多