0

I'm trying to implement a resizable vector in C without using the realloc and calloc functions. However, when I try to push a lot of values to the back of the array, I get a free(): invalid next size error. How can I remedy this?

I tried freeing the array right before I re-malloc it( the commented out block) but that causes a seg fault rather than the current error.

typedef struct {
size_t size;
size_t maxsize;
  int* array;
}
vector_int_t;

// Push a new value into the vector_int_t, allocate just enough memory if
// the internal array is full.
void vector_int_push_back_v1( vector_int_t* this, int value )
{ 
  if( this->size == this->maxsize ) {
    int* temp = malloc(  4 * (sizeof( this->maxsize)+1)  );
    size_t j = 0;
    for( size_t i = 0; i < this->maxsize; i++ ) {
      temp[j] = this->array[i];
      j++;
    }    
    temp[this->size] = value;
    /*if( this->size == 0 ) {
      this->array = malloc( 4 * (sizeof(this->maxsize)+2));
      this->size++;
      this->maxsize++;
      size_t z = 0;
      for( size_t y = 0; y < this->maxsize; y++ ) {
        this->array[z] = temp[y];
        z++;
      }
    }
    else {
      free( this->array );*/
      this->array = malloc( 4 * (sizeof(this->maxsize)+2)  );
      this->size++;
      this->maxsize++;
      size_t h = 0;
      for( size_t k = 0; k < this->maxsize; k++ ) {
        this->array[h] = temp[k];
        h++;
      }
    free( temp );
  }
  else {
    this->size++;
    this->maxsize++;
    this->array[this->size - 1] = value;
  }

}
bamfot13
  • 1
  • 1
  • Hello and welcome to Stack Overflow! When asking questions, please make sure that your code can be compiled. It doesn't hurt to clean up the code and leave only the essential parts to reproduce the problem. You can read more here: how to make a [mcve]. – giusti Oct 10 '19 at 16:27
  • Side-note: Extending your vector by only one or two elements whenever you reach capacity will produce extremely poor performance, especially since you're not using `realloc` (and therefore *never* reuse/resize a memory allocation, instead *always* copying to new memory); appending becomes a `O(n)` operation. Typically, you want to use some multiple of the current capacity; the simplest approach is doubling capacity each time, though that risks excessive unused memory when the final size only barely exceeds a power of two. Any reasonable multiple makes appending an amortized `O(1)` operation. – ShadowRanger Oct 10 '19 at 17:21

1 Answers1

0

This error typically happens when you write out of bounds of the allocated memory.

A very likely culprit is the use of sizeof in e.g. malloc( 4 * (sizeof( this->maxsize)+1) ).

If you want to allocate this->maxsize + 1 elements, you should use just that not sizeof.

But you should use sizeof to get the size of each element (e.g. sizeof *temp).

So the statement

int* temp = malloc(  4 * (sizeof( this->maxsize)+1)  );

should really look like

int* temp = malloc(  sizeof *temp * (this->maxsize+1)  );
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621