我在使用delete []运算符时遇到free()错误

时间:2014-08-13 20:39:23

标签: c++ heap-corruption delete-operator

我无法弄明白为什么我

*** Error in `./a.out': free(): invalid next size (fast): 0x00000000006db0e0 ***

尝试在以下代码中释放g,u和在subs_sum函数内声明的子集数组:

#include <iostream>
#include <algorithm>
#include <new>

using namespace std;


int
subs_sum(int n, int * numbers)
{

  int * g = new int [n-1];
  int * u = new int [n-1];
  int * subset = new int [n-1];
  int i, j;
  int sum = 0, nelem = 0;
  int found = 0;

  for (i=0; i<=n-1; i++)
  {
    g[i] = 0;
    u[i] = 1;
  }

  do
  {

    i = 0;
    j = g[0] + u[0];
    while ((j>=2) || (j<0))
    {
      u[i] = -u[i];
      i++;
      j = g[i] + u[i];
    }

    if (g[i])
    {
      g[i] = 0;
      nelem--;
      sum -= numbers[i];
    }
    else
    {
      g[i] = 1;
      nelem++;
      sum += numbers[i];
    }

    if (g[n-1]) break;

    if (sum == numbers[n-1])
    {

      if (nelem == n-1) // Success!!!
      {
        // Print partial result
        for (int ll=0; ll<=n-2; ll++)
          if (g[ll]) cout << numbers[ll] << "+";
        cout << "\b=" << sum << endl;

        found = 1;

        break;
      }

      if (n-1-nelem >= 2) // Go deeper.
      {

        int pp = 0;

        for (int ll=0; ll<=n-2; ll++)
          if (! g[ll]) subset[pp++] = numbers[ll];

        if (subs_sum(n-1-nelem, subset)) // Match found!!!
        {
          // Print partial result
          for (int ll=0; ll<=n-2; ll++)
            if (g[ll]) cout << numbers[ll] << "+";
          cout << "\b=" << sum << endl;

          found = 1;
          break;
        }
      }
    }
  }
  while(1);

  delete [] g;
  delete [] u;
  delete [] subset;

  return found;
}


int
main(void)
{
  int * numbers;
  int i;

  cin >> i;

  numbers = new int [i];

  for (int j=0; j<i; j++)
    cin >> numbers[j];

  cout << "Sorted Numbers: ";

  sort(numbers, numbers+i);

  for (int j=0; j<i; j++)
    cout << numbers[j] << " ";
  cout << endl;

  subs_sum(i, numbers);

  delete [] numbers;

  return 0;
}

如果我发表评论

,我没有任何问题
delete [] g;
delete [] u;
delete [] subset;

并且程序按预期运行:

$ echo -e "11\n1\n41\n10\n24\n5\n12\n6\n14\n9\n35\n7\n" | ./a.out 
Sorted Numbers: 1 5 6 7 9 10 12 14 24 35 41 
1+5=6
9+12+14=35
7+10+24=41

有什么想法吗?感谢

2 个答案:

答案 0 :(得分:2)

你没有让你的阵列足够大。将它们分配为new int[n]而不是new int[n-1]

答案 1 :(得分:2)

int * g = new int [n-1];

分配n-1 int数组,索引0到n-1-1。

稍后,您访问:

for (i=0; i<=n-1; i++)
  {
    g[i] = 0;
    u[i] = 1;
  }

这是最后一次迭代:

g[n-1] = 0;

缓冲区溢出是未定义行为的常见情况,这意味着可能发生任何事情。

在这种情况下,你似乎对你的分配器的簿记进行了混乱,这实际上已被诊断出来了 这种幸福的结果无法保证。

为什么说free发现了错误,而不是delete? 好吧,封面下的delete-expression调用对象上的dtor(除非基本类型为no-op),然后是函数operator delete。 后者通常只是将请求转发给free