note: I suspect this question to be a duplicate and I've found many similar questions but I haven't found an exact duplicate. Therefore I post an answer. Should someone find an exact duplicate I'll remove this answer.
Why the above program gives segmentation fault?
The short answer is that you have a type mismatch when calling fun. You don't give fun a "pointer to pointer to char" as it expects. Consequently, it fails big time.
But what do you then pass to fun? And how should you have found out that something was wrong?
The answer is: Set compiler warning level high and consider all warnings to be errors
For gcc that could be:
gcc -xc -Wall -pedantic -Werror main.c
(Other compilers have similar options)
On my system I get:
In function 'main':
error: passing argument 1 of 'fun' from incompatible pointer type [-Werror=incompatible-pointer-types]
   13 | fun(&a );
      |     ^~
      |     |
      |     char (*)[100]
note: expected 'char **' but argument is of type 'char (*)[100]'
    3 | void fun(char** a)
      |          ~~~~~~~^
so it's clear that something is wrong and the following line tells it all:
note: expected 'char **' but argument is of type 'char (*)[100]'
you pass char (*)[100] instead of char **
But what is char (*)[100]?
It's a "pointer to an array of char". Since fun uses it as "pointer to pointer to char" you have undefined behavior (which in your case resulted in a seg fault). That is - fun would expect *a to be a "pointer to char" but you passed "pointer to an array of char" so *a is not a "pointer to char".
It's undefined behavior so we can't tell what is going on. However, on many systems it will read the string "pinky" and interpretate it as a pointer to char which will fail big time.