Take the following code :
int *p = malloc(2 * sizeof *p);
p[0] = 10; //Using the two spaces I
p[1] = 20; //allocated with malloc before.
p[2] = 30; //U
When you use * (p+3), you're addressing out of bounds even with using 2*sizeof(* p), hence you're accessing an invalid memory block, perfect for seg faults.
You specify the size b/c otherwise, the function doesn't know how big of a block out of the heap memory to allocate to your program for that pointer.