This is dangerous because the string is not-modifiable. Attempting to do so results in undefined behavior.
So it's preferred to do:
const char *a = "test";
You are correct that "test"
in this case is not allocated on the heap or the stack* and instead lies in static memory that is not-modifiable.
*The standard says nothing about the stack or heap, though that's how it's usually implemented.
On the other hand:
char a[] = "test";
Is safe to modify since it's just short-form for:
char a[] = {'t','e','s','t','\0'};
which is an ordinary modifiable array.