【问题标题】:Deleting array - heap corruption detected删除数组 - 检测到堆损坏
【发布时间】:2012-06-14 19:33:38
【问题描述】:

我有这个简单的代码(为了简化,重要的部分可能只有构造函数和 add 方法。)(代码更新)。

#include "general.h"
template <class T>
class Template
{
private:
    T* oldArr;
    T* newArr;
    int oldArrTop;
    int oldArrLen;
public:
    Template();
    ~Template();
    void add(const T& val);
    void print();
};

template <class T>
Template<T>::Template()
{
    oldArr=new T[2];
    oldArrTop=0;
    oldArrLen=2;
    newArr=new T[4];
    //newArr's length is always 2.
}

template <class T>
Template<T>::~Template()
{
    delete[] oldArr;
    delete[] newArr;
}

template <class T>
void Template<T>::add(const T& val)
{
    //add normally
    oldArr[oldArrTop]=val;
    //need to copy 2 elements
    if( oldArrTop%2==1 )
    {
        newArr[oldArrTop]=oldArr[oldArrTop];
        newArr[oldArrTop-1]=oldArr[oldArrTop-1];
    }
    oldArrTop++;
    //need to double array's size
    if( oldArrTop==oldArrLen )
    {
        delete[] oldArr;
        oldArr=newArr;
        oldArrLen*=2;
        newArr=new T[oldArrLen*2];
    }
}

template <class T>
void Template<T>::print()
{
    for (int i=0; i<oldArrTop; i++)
        cout<<oldArr[i]<<endl;
}

这是使用模板的代码:

Template<int> a=Template<int>();
    for(int i=0;i<10;i++)
        a.add(i);
    a.print();

但是,当我使用带有整数的模板时(例如),我第一次删除数组时(第一次进入 add 中的“需要加倍数组的大小”部分时,我得到一个堆损坏错误。任何人都知道问题是什么? 非常感谢!


我不确定是什么修复了它,但是堆损坏错误消失了。但是,它不是打印从 0 到 9 的数字,而是打印一个奇怪的数字 (-842105421)。任何想法为什么?

【问题讨论】:

  • 我相信 delete[] oldArr;只是删除指向数组中第一个元素的指针。您必须遍历并删除数组中的每个单独元素
  • @timkd127 除非他将其设为指针数组,否则这是不必要的。 @Idan:您是否尝试过将oldArrTop++ 移出作业?也许你的编译器有一个奇怪的顺序
  • 你能贴出使用这个的代码吗?
  • 你违反了the rule of three
  • 尝试在每次添加后打印对象,看看结果如何,您应该能够通过自己逐步执行逻辑来弄清楚发生了什么

标签: c++ memory-management


【解决方案1】:

我认为您可以在这里访问分配区域后面的内存:

oldArr[oldArrTop]=newArr[oldArrTop];

当您添加第二个值时,oldArrTop 将变为 2,您将输入 if( oldArrTop%2==0 )。在此,如果您的 oldArr 只有两个分配的元素,但您尝试访问第三个(因为 oldArrTop==2 意味着第三个元素):

oldArr[2]=newArr[2];

【讨论】:

  • 这是一个错误。我的意思是写 newArr[oldArrTop-1]=oldArr[oldArrTop-1]; newArr 是一个具有双倍 oldArr 长度的数组,其中每两个版本后 oldArr 的元素被复制到 newArr。
  • @Idan 这绝对是正确的答案。现在发布代码的方式,在第二次添加 oldArrTop 在该行等于 2 之后,它通过 oldArrtop%2 == 0 并尝试写入数组边界之外的 oldArr[2]。然后当程序尝试delete oldArr[] 时,它会检测到堆损坏
  • @Idan 换句话说,你必须把oldArr[oldArrTop++]=val放在检查if(oldArrTop==oldArrLen)之后以避免内存溢出
  • 哦,所以我需要 oldArrTop-1 和 oldArrTop-2! (或在第二个 if... 之后增加 oldArrTop) 明白了。谢谢!但我还有另一个问题:它现在没有崩溃,但这是我的输出:-842150451 -842150451 -842150451 -842150451 4 5 6 7 8 9(换行而不是空格)。 (而不是从 0 到 9 的数字)。关于它为什么会发生的任何想法?
  • @Idan 我怀疑您现在看到的问题是您将项目复制到newArr 的方式的结果。它似乎缺少前 4 个元素 (0 - 3)
【解决方案2】:

只需使用std::vector&lt;T&gt;。它会为你管理内存(如果需要,数组大小会加倍:))

【讨论】:

  • 他可能正在使用 stl 不可用的系统
  • 我怀疑他在 2012 年使用的编译器,它支持模板,但没有标准库。 @伊丹?
  • 或者使用 STL 编码可能完全违反了公司政策。我以前工作过的几家游戏公司都有这样的政策,因为使用任何模板化的东西都会导致代码很快膨胀
  • 不用猜我为什么要这么做——这是一个家庭作业:)
猜你喜欢
  • 2019-08-28
  • 2016-04-01
  • 2011-07-24
  • 1970-01-01
  • 1970-01-01
  • 2017-01-18
  • 2018-03-26
  • 1970-01-01
  • 2020-10-02
相关资源
最近更新 更多