can you explain why this code needs a double pointer as parameter?
/*
 * Read in pixel array by following these instructions:
 *
 * 1. First, allocate space for m `struct pixel *` values, where m is the 
 *    height of the image.  Each pointer will eventually point to one row of 
 *    pixel data.
 * 2. For each pointer you just allocated, initialize it to point to 
 *    heap-allocated space for an entire row of pixel data.
 * 3. Use the given file and pixel_array_offset to initialize the actual 
 *    struct pixel values. Assume that `sizeof(struct pixel) == 3`, which is 
 *    consistent with the bitmap file format.
 *    NOTE: We've tested this assumption on the Teaching Lab machines, but 
 *    if you're trying to work on your own computer, we strongly recommend 
 *    checking this assumption!
 * 4. Return the address of the first `struct pixel *` you initialized.
 */
struct pixel **read_pixel_array(FILE *image, int pixel_array_offset, int width, int height) {

    // Allocate space
    struct pixel **allocatedMem = malloc(sizeof(struct pixel *) * height);

    for (int i = 0; i < height; i++){
        allocatedMem[i] = malloc((sizeof(struct pixel)) * width);
    }

    fseek(image, pixel_array_offset, SEEK_SET);

    unsigned char blue;
    unsigned char green;
    unsigned char red;

    for (int i = 0; i < height; i++){
        for (int j = 0; j < width; j++){

        fread(&blue, 1, 1, image);
       
        fread(&green, 1, 1, image);

        fread(&red, 1, 1, image);

        struct pixel pixels= {blue, green, red};

        allocatedMem[i][j] = pixels;
    }
  }

  return allocatedMem;

}
