Search code examples
c++freedynamic-allocation

free(): invalid next size (fast) after several calls


I am entirely unsure how this function can possibly have a bug with memory allocation.

template <typename T, typename U> // x -> ax+b
void transform_coords(double a, double b, int n, const T* oldc, U* newc) {
  int i, j, q0, q;
  if (n<2) return;

  int *p = new int[n]; // Pascal's triangle
  p[0] = 1;
  for (i=1; i<n; ++i) p[i] = 0;
  for (i=0; i<n; ++i) newc[i] = 0;

  for (j=0; j<n; ++j) {
    for (i=0; i<n; ++i) {
      if (p[i]==0) break;
      double m = p[i];
      if (i!=j) m *= std::pow(a,j-i);
      if (i!=0) m *= std::pow(b,i);
      newc[i] += m * oldc[j];
    }
    for (i=1, q=1; q; ++i) {
      q0 = p[i];
      p[i] += q;
      q = q0;
    }
  }

  delete[] p;
}

On the third call I get

*** glibc detected *** ./bin/bin_var: free(): invalid next size (fast)

If I comment out delete[] p; it runs fine through all the calls.

As far as I see, concerning memory allocation, this function is equivalent to

void transform_coords(int n) {
  if (n<2) return;
  int *p = new int[n];
  delete[] p;
}

Solution

  • The problem is in one of your loops. As said in this post on Error: free(): invalid next size (fast):

    You may be overflowing a buffer or otherwise writing to memory to which you shouldn't be writing, causing heap corruption.

    My best guess is this loop:

    for (i=1, q=1; q; ++i) {
      q0 = p[i];
      p[i] += q;
      q = q0;
    }
    

    if p array is not 0 terminated, this will overwrite memory in the heap.

    That being said, if you use std::vector instead of a manually allocated array, your code would be much clearer.