char a[] = "あああ";
 ┌─┬─┬─┬─┬─┬─┬─┐
 │  あ  │  あ  │  あ.  │\0│
 └─┴─┴─┴─┴─┴─┴─┘
   ↑
 「確保」 されるのはこの領域

char *b = "いいい";
 ┌─┬─┬─┬─┐             ┌─┬─┬─┬─┬─┬─┬─┐
 │     ========================>※│  い  │  い  │  い.  │\0│
 └─┴─┴─┴─┘      参照    └─┴─┴─┴─┴─┴─┴─┘
   ↑
 「確保」 されるのはこの領域

char *b = "いいい"; の時点で※の領域が確保されるわけではない。
確保されるのは char *b 分の領域のみ。

※の領域はプログラム起動時にメモリ上のどこかに配置される。
どこに配置されるかは処理系依存。


ちなみに変数のアドレスを printf("%p\n", b); で表示するのは間違い。
正しくは & 演算子を使う。

printf("%p, %d\n", &a, sizeof(a));
printf("%p, %d\n", &b, sizeof(b));