Increase dynamic array size with a function; free error, invalid next size (fast)

178 Views Asked by At

I need to create a dynamic array and put five number, after there is another input which is how much I have to increase the array size. When all input are ended I am going to increase the array size and put numbers inside.

everything works but free return me this error: "free(): invalid next size (fast): 0x00000..."

I think there are errors inside "extend" function

void extend(int *V, int n, int s)
{
    int *pt;
    pt = realloc(V, n*sizeof(int));
    int i;
    pt[5]=s;
    for(i=6;i<(5+n);i++)
        pt[i] = pt[i-1]*2;
}

int main()
{
    int *v;
    int n,i, sum;
    sum = 0;

    v = malloc(sizeof(int)*5);

    for(i=0;i<5;i++)
    {
        scanf("%d", &v[i]);
        sum+=v[i];
    }   

    scanf("%d", &n);

    extend(v,n,sum);

    for(i=0;i<(5+n);i++)
        printf("%d\n", v[i]);
    free(v);
    return 0;
}
4

There are 4 best solutions below

8
On BEST ANSWER

The function does not change the original variable v. It should be defined at least like

void extend(int **V, int n, int s)
{
    int *pt;
    pt = realloc(*V, n*sizeof(int));
    if ( pt )
    {
        int i;
        pt[5]=s;
        for(i=6; i < n; i++)
        pt[i] = pt[i-1]*2;
        *V = pt; 
    }
}

Or

int extend(int **V, int n, int s)
{
    int *pt;

    pt = realloc(*V, n*sizeof(int));
    int success = pt != NULL;

    if ( success )
    {
        int i;
        pt[5]=s;
        for(i=6; i < n; i++)
        pt[i] = pt[i-1]*2;
        *V = pt; 
    }

    return success;
}

And the function should be called lije

extend( &v,n,sum);

Take into account that the function is unsafe because in general n can be less than or equal to 5. And this statement

for(i=6;i<(5+n);i++)
          ^^^^

can result in undefined behavior.

Or the function shall allocate n + 5 elements. For example

    pt = realloc(*V, ( n + 5 )*sizeof(int));
                     ^^^^^^^^

Also the using of this magic number 5 is unclear and does not make sense.

0
On

The realloc returns a pointer to the new memory block but you do not return that to the caller. Instead v in main, is the same v that was before the call but now invalid and which causes your error no doubt, easiest is to return pt instead:

int* extend(int *V, int n, int s)
{
    int *pt;
    pt = realloc(V, n*sizeof(int));
    int i;
    pt[5]=s;
    for(i=6;i<(5+n);i++)
    pt[i] = pt[i-1]*2;
    return pt;
}
...
v = extend(v,n,sum);

another thing that is not correct is your initialization of the new elements, n should contain the number of new elements plus any old since you want the allocated the block to be bigger. better to give old and new number of elements to it:

int* extend(int *V, int oldNumber, int newNumber, int s)
{
    int *pt = realloc(V, newNumber*sizeof(int));
    int i;
    if (pt==NULL) 
    {
      fprintf(stderr,"Out of memory\n");
      return V;
    }
    pt[oldNumber]=s;
    // now you can initialize the rest of the array
    for(i=oldNumber+1;i<newNumber;i++) 
      pt[i] = pt[i-1]*2;
    return pt;
}
...
v = extend(v,5,n,sum);
0
On

Grow an array like this

  int capacity = 10; // don't start off as tiny
  ENTRY *array = malloc(capacity * sizeof(ENTRY));
  int N = 0;   //number of entries.

To add

   int addentry(ENTRY *entry)
   {
      ENTRY *temp;

      if(N >= capacity)
      {
          temp = realloc(array, (capacity + capacity/2) * sizeof(ENTRY));
          if(!temp)
            goto out_of_memory;
          array = temp;
          capacity = capacity + capacity/2;
      }
      array[N] = *entry;
      N++;
      return 0;
    out_of_memory:
        //always a problem, maybe terminate program here
        // as it is, just shunt up
        return -1;
   }

You need the temp because realloc returns 0 on failure but keeps the argument intact, so you need to keep array to destroy it gracefully. Grow by about 1.5, doubling is too aggressive and reallocating on every call is too expensive.

4
On

Well, in function extend:

  • You are allocating pt to a memory block of n entries
  • You are attempting to access pt at indexes beyond n-1

More specifically, with:

pt = realloc(V, n*sizeof(int));
for (i=6; i<(5+n); i++)
    pt[i] = ...

You are performing illegal memory-access operations on:

  • pt[n]
  • pt[n+1]
  • pt[n+2]
  • pt[n+3]
  • pt[n+4]