title: Correctly allocating multi-dimensional arrays
body: <p><em>The intent of this question is to provide a reference about how to correctly allocate multi-dimensional arrays dynamically in C. This is a topic often misunderstood and poorly explained even in some C programming books. Therefore even seasoned C programmers struggle to get it right.</em> </p>
  
  <hr>
  
  <p>I have been taught from my programming teacher/book/tutorial that the correct way to dynamically allocate a multi-dimensional array is by using pointer-to-pointers. </p>
  
  <p>However, several high rep users on SO now tell me that this is wrong and bad practice. They say that pointer-to-pointers are not arrays, that I am not actually allocating arrays and that my code is needlessly slow. </p>
  
  <p>This is how I was taught to allocate multi-dimensional arrays:</p>
  
  <pre><code>#include &lt;stdlib.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;assert.h&gt;
  
  int** arr_alloc (size_t x, size_t y)
  {
    int** pp = malloc(sizeof(*pp) * x);
    assert(pp != NULL);
    for(size_t i=0; i&lt;x; i++)
    {
      pp[i] = malloc(sizeof(**pp) * y);
      assert(pp[i] != NULL);
    }
  
    return pp;
  }
  
  int** arr_fill (int** pp, size_t x, size_t y)
  {
    for(size_t i=0; i&lt;x; i++)
    {
      for(size_t j=0; j&lt;y; j++)
      {
        pp[i][j] = (int)j + 1;
      }
    }
  
    return pp;
  }
  
  void arr_print (int** pp, size_t x, size_t y)
  {
    for(size_t i=0; i&lt;x; i++)
    {
      for(size_t j=0; j&lt;y; j++)
      {
        printf("%d ", pp[i][j]);
      }
      printf("\n");
    }
  }
  
  void arr_free (int** pp, size_t x, size_t y)
  {
    (void) y;
  
    for(size_t i=0; i&lt;x; i++)
    {
      free(pp[i]);
      pp[i] = NULL;
    }
    free(pp);
    pp = NULL;
  }
  
  
  int main (void)
  {
    size_t x = 2;
    size_t y = 3;
    int** pp;
  
    pp = arr_alloc(x, y);
    pp = arr_fill(pp, x, y);
    arr_print(pp, x, y);
    arr_free(pp, x, y);
  
    return 0;
  }
  </code></pre>
  
  <p>Output</p>
  
  <pre><code>1 2 3
  1 2 3
  </code></pre>
  
  <p>This code works just fine! How could it be wrong?</p>