Undefined behavior. It cannot (and shouldn't be attempted to) be predicted and relied upon*. The thing is, you just didn't assign any value to your pointer so it was uninitialized, i.e. holding a semi-random unpredictable value. If that value happens to be an address inside a memory region that's writable, using that spot in memory will "succeed" but corrupt something else because it's not your memory. If it's an address where no writable memory is allocated, you'll crash attempting to access the memory there.
It's important to realize that not every errornous behavior or action immediately results in an exception being thrown. It can for example also just cause subtle corruption of data or other issues that may or may not cause bigger trouble later.
Think of it like this:
You just wrote your shopping list on that random piece of paper you found. There is no way of saying whether that paper was actually the next empty page in your notebook anyway or it was yesterday's newspaper, your notes for today's speech, your roommate's rare author-signed copy of Goethe's "Werther" or incidentally not paper at all but your slumbering cat's belly. The outcomes can differ wildly - from everything working as expected to you getting scratched badly by a fairly furious feline, and the effects of your actions could even manifest themselves with a time delay, such as when your roommate returns from his Karate training and realizes that you blatantly vandalized his most precious piece of family heritage. Attempting to rationalize this and analyze under what conditions you can get away with it is like thinking the issue here was the wrong choice of pen, not compatible with the squishy nature of your cat's belly without applying enough force to wake her up, instead of realizing that none of this would have happened if you had stuck to using your notepad in the first place.
*: Of course, it's possible to understand what happens technically and why, and it can be quite educational. Once you understand the low-level details of it deeply enough, you can probably predict what will happen. But if you discover that a certain scenario seems to work "reliably" despite it being undefined behavior (even if you checked the generated machine code and can statically say for sure that it will work in that binary), it's still a bad idea to rely on this discovery, because one manifestation of undefined behavior can also be that it works on a specific platform or with a specific compiler only. Essentially, the compiler has to follow the specifications exactly in every scenario that is defined by them, but is allowed to do whatever it wants (or whatever was easy to do when writing the code, such as not caring about what happens in "impossible" situations) in case of things that involve "undefined behavior".