title: Extending and shrinking array using realloc
body: <p>I'm trying to write a program which first dynamically initialises a queue array for 100 int elements. Whenever the queue is full and another element is supposed to be queued, the original array is supposed to double it's size so new elements can be inserted. In case elements are dequeued, and the amount of elements the queue consists of falls below half of its actual size, the queue size is supposed to be cut in half. However, its size should never fall below 10. </p>
  
  <p>I'm trying to expand and shrink the array with realloc, however I'm having some problems understanding its mechanics, especially when returning a new pointer. Here is my program (with some redundant <code>printf</code> for <code>debugging</code> reasons):</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;stdbool.h&gt;
  #include &lt;iso646.h&gt;   
  
  
  
  void enqueue(int arr[], int* lastElementIdx, int *length, int element);
  int dequeue (int arr[], int* lastElementIdx, int *length);
  void printQueue(const int arr[], int lastElementIdx);
  int expandArray(int *arr, int length);
  int shrinkArray(int *arr, int length, bool min);
  
  
  void test1(int *arr, int* lastElementIdx, int *length)
  {
      int* temp = arr;
      printf("\nprintQueue #1:\n");                   //print queue, should be empty
      printQueue(temp, *lastElementIdx);
  
      for(int i = 1; i &lt;= 100; i++)                   //insert elemnts to queue
          enqueue(temp, lastElementIdx, length, i);
  
      printf("\nprintQueue #2:\n");                   //print queue
      printQueue(temp,*lastElementIdx);
  
      printf("\nAusgabe von dequeue:\n");             // dequeue array
      while(*lastElementIdx &gt; *length/4)
          printf("\naddress: %p\tElement: %d\n", temp, dequeue(temp, lastElementIdx, length));
  
      free(temp);
  
  }
  
  
  void test2(int *arr, int* lastElementIdx, int *length)
  {
      int *temp = arr;
      printf("\n************\nEnqueue beyond queue[N-1]:\n");
      puts("Queue aufbauen...");
      for(int i = 1; i &lt;= 150; i++)
          enqueue(temp, lastElementIdx, length, i);
  
      printf("\nprintQueue:\n");
      printQueue(temp,*lastElementIdx);
  
      printf("\nDequeue:\n");
      while(*lastElementIdx &gt; *length/4)
          printf("\naddress: %p\tElement: %d\n", temp, dequeue(temp, lastElementIdx, length));
  
      free(temp);
  
  }
  
  
  
  int main(int argc, char const *argv[])
  {
      int startingPoint = -1, *lastElementIdx = &amp;startingPoint, N = 100, *length = &amp;N;
      int *queue = (int*) calloc(*length, sizeof(*queue));
  
      test2(queue, lastElementIdx, length);
      queue = (int*) calloc(*length, sizeof(*queue));
      test1(queue, lastElementIdx, length);
  
  
      return 0;
  }
  
  int expandArray(int *arr, int length)
  {
      /*function to double the array size*/
  
      length *= 2;
      int *temp;
      temp = (int*) realloc(arr, sizeof(*arr)*length);
      if (!temp) {
          free(temp);
      }
      else{
          if (arr != temp) {
              free(arr);
              arr = temp;
          }
          else{
              arr = temp;
          }
      }
  
      printf("EXPAND ARRAY: %p\n", arr);
      return length;
  }
  
  int shrinkArray(int *arr, int length, bool min)
  {
      /*function that cuts array in half*/
      int *temp;
  
      if (min){
          length = 10;
      }
      else{
          length /= 2;
      }
  
      temp = (int*) realloc(arr,sizeof(*arr)*length);
      if (!temp) {
          free(temp);
      }
      else{
          arr = temp;
      }
  
      printf("SHRINK ARRAY: %p\n",arr);
      return length;
  }
  
  void enqueue(int arr[], int* lastElementIdx, int *length, int element)
  {
      if ( *lastElementIdx &lt; *length - 1){        //checks if there's space for another element
          arr[*lastElementIdx + 1] = element;     //if yes, insert element after lastElementIdx
          (*lastElementIdx)++;                    //increment lastElementIdx
      }
      else{
          *length = expandArray(arr, *length);    //if not, expand array
      }
  }
  
  
  
  int dequeue (int arr[], int* lastElementIdx, int *length)
  {
      printf("address before:\t%p\tLast Element: %d\tLength: %d\n", arr,*lastElementIdx, *length);
      int *p = arr;
      if(*lastElementIdx &gt; -1){               //Checks if there is an element in the queue
          if (*lastElementIdx + 2 &lt; *length/2 and *lastElementIdx + 2 &gt; 10) {
              bool min = false;
              *length = shrinkArray(arr, *length, min);
          }
          else if (*lastElementIdx + 2 &lt; 10){
              bool min = true;
              *length = shrinkArray(arr, *length, min);
          }
  
          (*lastElementIdx)--;        //shift position of last element
          printf("address afterw:\t%p\tLast Element: %d\tLength: %d\n", arr, *lastElementIdx,*length);
          return *(p + *lastElementIdx + 1);
      }
  
  
      return 0;
  }
  
  
  
  void printQueue(const int arr[], int lastElementIdx)
  {
      while( lastElementIdx &gt; -1){
          printf("%d\t", *(arr + lastElementIdx));
          lastElementIdx--;   
      }   
  }
  </code></pre>
  
  <p>However I keep getting 2 errors. The first one is here:</p>
  
  <pre><code>if (arr != temp) {
              free(arr);
              arr = temp;
          }
  </code></pre>
  
  <p>saying <code>error for object 0x1001013b0: pointer being freed was not allocated</code>. 
  I implemented this line in the first place, because after a while I figured out the pointer address of the reallocated memory changes sometimes. If I delete that <code>if statement</code> I still keep getting an error, this time being in this line:</p>
  
  <pre><code>temp = (int*) realloc(arr, sizeof(*arr)*length);
  </code></pre>
  
  <p>the message being: <code>malloc: *** error for object 0x100500000: pointer being realloc'd was not allocated</code></p>
  
  <p>I should also add, that in both cases, sometimes the program is executed without any problems. In the latter case, the error is alternating between the realloc line in <code>expandArray</code> and the one in <code>shrinkArray</code>. 
  I don't really understand why this happens, and how to handle the situation when <code>realloc</code> returns a new pointer address. Inspired by similar posts, I tried different approaches, like passing <code>int **arr</code> instead of <code>int *arr</code> to both <code>expandArray</code> and <code>shrinkArray</code>. I also tried different methods to free the original array after realloc like </p>
  
  <pre><code>temp = (int*) realloc(arr,sizeof(*arr)*length);
  if (!temp) {
      free(temp);
  }
  else{
      free(arr);
      arr = temp;
  }
  </code></pre>
  
  <p>always with the same error message. And I hoped freeing the memory after each test function and allocating new memory in the <code>main function</code> for the queue array before calling the second test functions would solve the problem, when in fact it didn't. </p>
  
  <p>I really appreciate any kind of help on this. </p>