I need some explanation for some commands in this particular piece of code:
#inlcude <stdlib.h>
#define PTRS 5
char *p[PTRS];
size_t nbytes = 10;
int i;
/* Allocating memory */
for (i=0; i<PTRS; i++){
    printf("malloc of %10lu bytes ", nbytes);
    if ((p[i] = (char *)malloc(nbytes)) == NULL){
        printf("failed\n");
    } else {
        printf("succeeded\n");
    nbytes *= 100;
}
/* Free the memory allocated */
for (i=0; i<PTRS; i++){
    if(p[i]){
        free(p[i]);
        p[i] = NULL;
    }
}
First one is
char *p[PTRS];
Does this line declare a pointer to an array or does it declare an array of pointers to char?
p[i] = (char *)malloc(nbytes) I understand that as i increases, p[i] will contain a pointer to the allocated memory called by malloc if it's successfully processed, and p[i] will beNULL` if no such memory can be prepared.
Second one is
if (p[i]){
    free(p[i]);
    p[i] = NULL;
}
This only frees memory if p[i] has any value (in this case a pointer to the memory). What happens if we remove if(p[i]) and only use free(p[i] and p[i] = NULL? Can we free a NULL pointer?
 
     
    