C++ double free or corruption (out) 错误

c++ double free or corruption (out) error

打印输出后出现 "Double free or corruption(out)" 错误。但此错误仅适用于少量输入。对于更大的输入程序不会抛出该错误。当我在 main 中创建多维数组并删除它们时,我没有收到错误。我在这里只发布了与此问题相关的代码部分。请解释如何解决这个问题。

#include<iostream>
#include<vector>
using namespace std;

class Knapsack{
  public:
    int noItems, capacity, value, weight;
    int *weightArray, *valueArray;
    int **ValueMatrix, **BacktrackMatrix;
    vector<int> itemsChosen;
    ~Knapsack();
    void getInputs();              // reads in data
    void findItems();         // calculates best value of items
    void backTrack(int row, int col); // backtracks items selected
    void print();                       //prints out data
};

Knapsack::~Knapsack()
{
  delete[] weightArray;
  delete[] valueArray;
  for(int i=1;i<=noItems;i++)
  {
    delete[] ValueMatrix[i];
  }
  delete[] ValueMatrix;
  for(int i=1;i<=noItems;i++)
  {
    delete[] BacktrackMatrix[i];
  }
  delete[] BacktrackMatrix;
}

void Knapsack::getInputs()
{
  cin>>noItems;
  cin>>capacity;
  weightArray=new int[noItems];
  valueArray=new int[value];
  for(int i=1;i<=noItems;i++)
  {
    cin>>value;
    valueArray[i]=value;
  }
  for(int i=1;i<=noItems;i++)
  {
    cin>>weight;
    weightArray[i]=weight;
  }
  ValueMatrix=new int*[noItems];
  for(int i=1;i<=noItems;i++)
  {
    ValueMatrix[i]=new int[capacity+1];
  }
  BacktrackMatrix=new int*[noItems];
  for(int i=1;i<=noItems;i++)
  {
    BacktrackMatrix[i]=new int[capacity+1];
  }
}

int main()
{
  Knapsack *knap=new Knapsack();
  knap->getInputs();
  knap->findItems();
  knap->print();
  delete knap;
  return 0;
}

我认为您的问题的根源是由 valueArray 的分配以及您迭代越界的事实引起的。

valueArray=new int[value]; 使用大小为 value 的数组初始化 valueArray,这是一个未初始化的变量。也许你打算使用 noItems?

此外,正如 songyuanyao 在评论中指出的那样,您的 for 循环看起来像 for(int i=1;i<=noItems;i++),它在 1 开始计数器并在 noItems 结束计数器,这是错误的。在许多语言中,包括 C++,数组从索引 0 开始(意味着第一项是 array[0],而不是 array[1]),最后一项是数组大小减去一个(所以具有 5 个元素的数组的最后一项是 array[4]).

如果您将 for 循环更改为从 0 开始并在 noItems 之前结束一个元素,您应该是金色的。那将是 for(int i = 0; i < noItems; i++ )

较小的分配可能发生的情况是不同的内存块按顺序排列在内存堆的同一区域中,因此当您用数据溢出缓冲区时,您正在粉碎 new 的簿记数据。

当您有较大的分配时,新内存不能干净地放入堆的空闲 space,因此分配器最终会在分配之间留下一些空隙 space。因此,小的溢出不会破坏堆信息。