在使用delete[]操作符时,我得到了free()错误。

时间:2022-09-05 21:52:51

I could not figure out why I got

我搞不懂为什么会这样

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

while trying to free g, u and subset arrays declared inside subs_sum function in the following code:

当尝试释放subs_sum函数中声明的g、u和子集数组时,代码如下:

#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;
}

I got no one issue if I comment out

如果我发表意见的话,我不会有任何问题

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

and program ran as expected:

程序按预期运行:

$ 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

Any idea? Thanks

任何想法?谢谢

2 个解决方案

#1


2  

you are not making your arrays big enough. Allocate them as new int[n] instead of new int[n-1]

你的数组不够大。将它们分配为新的int[n]而不是新的int[n-1]

#2


2  

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

Allocates an array of n-1 int, indices 0 to n-1-1.

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

Later, you access:

稍后,您访问:

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

Which is in the last iteration:

在最后一次迭代中:

g[n-1] = 0;

Buffer overrun is a common case of undefined behavior, which means anything may happen.

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

Seems in this case you scrambled the bookkeeping of your allocator, which was actually diagnosed.
Such a happy outcome cannot be guaranteed.

在这种情况下,你似乎打乱了分配器的簿记,这实际上是被诊断出来的。这样一个愉快的结果是不能保证的。

Why does it say free found the error, and not delete?
Well, the delete-expression under the covers calls the dtor on the object (unless trivial aka no-op as for primitive types) and then the function operator delete.
The latter commonly just forwards the request to free.

为什么它说free找到错误,而不删除?好吧,隐藏的删除表达式调用对象上的dtor(除非是简单的无操作,如原始类型),然后函数操作符delete。后者通常只是将请求转发给free。

#1


2  

you are not making your arrays big enough. Allocate them as new int[n] instead of new int[n-1]

你的数组不够大。将它们分配为新的int[n]而不是新的int[n-1]

#2


2  

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

Allocates an array of n-1 int, indices 0 to n-1-1.

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

Later, you access:

稍后,您访问:

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

Which is in the last iteration:

在最后一次迭代中:

g[n-1] = 0;

Buffer overrun is a common case of undefined behavior, which means anything may happen.

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

Seems in this case you scrambled the bookkeeping of your allocator, which was actually diagnosed.
Such a happy outcome cannot be guaranteed.

在这种情况下,你似乎打乱了分配器的簿记,这实际上是被诊断出来的。这样一个愉快的结果是不能保证的。

Why does it say free found the error, and not delete?
Well, the delete-expression under the covers calls the dtor on the object (unless trivial aka no-op as for primitive types) and then the function operator delete.
The latter commonly just forwards the request to free.

为什么它说free找到错误,而不删除?好吧,隐藏的删除表达式调用对象上的dtor(除非是简单的无操作,如原始类型),然后函数操作符delete。后者通常只是将请求转发给free。