ポインタは4つの状態がある。
①確保したメモリをさしている状態。p = (int*)malloc(sizeof(int) * N); , int &a )
②変数宣言直後の状態。どこを指しているかわからない状態。(int *p;)
③解放したメモリを指している状態。
④NULL をさしている状態。つまりどこも指していない状態。
詳しくは下記から
【C言語】「NULL」の意味とNULLを用いた「安全なポインタの使い方」 | だえうホームページ
malloc 関数で確保したメモリを指しているポインタを free 関数で解放すると、そのポインタの指すメモリが解放されます。
これにより、free 関数に指定したポインタは、解放したメモリを指している状態になります。
上記で安全にアクセス可能な状態は、①の確保したメモリをさしている状態のみ
他の状態で値を変更したり、取得しようとすると、セグフォもしくはabortが起こる。
一方ポインタの扱いが厄介なのはプログラムが判断できるのは
①ポインタがNULLをさしている。
②それ以外
なので下記を気をつけるとセグフォを防げる。